【发布时间】:2016-04-15 10:26:03
【问题描述】:
我正在做一些原型设计,并有一个像这样的简单模型
class SampleModel(models.Model):
user_id = models.IntegerField(default=0, db_index=True)
staff_id = models.IntegerField(default=0, db_index=True)
timestamp = models.DateTimeField(default=timezone.now, db_index=True)
objects = AsOfManager()
现在我们需要执行需要自连接的查询,用原始 SQL 编写的查询是这样的:
SELECT X.* FROM no_chain_samplemodel as X
JOIN (SELECT user_id, MAX(timestamp) AS timestamp
FROM no_chain_samplemodel
GROUP BY user_id) AS Y
ON (X.user_id = Y.user_id and X.timestamp = Y.timestamp);
此查询应为每个 user_id 返回按时间戳排序的最后一行。这个“链”中的每一个(与 user_id 相关的行)都可能有数千行。
现在我可以使用原始 SQL,但我失去了可组合性,我想返回另一个查询集。 同时也可以让编写原始 SQL 更容易,所以我想我可以使用数据库视图。
视图可能是这样的
CREATE VIEW no_chain_sample_model_with_max_date AS SELECT user_id AS id, MAX(timestamp) AS timestamp
FROM no_chain_samplemodel
GROUP BY user_id;
所以引用视图的模型可以简单地像这样:
class SampleModelWithMaxDate(models.Model):
class Meta:
managed = False
db_table = 'no_chain_sample_model_with_max_date'
id = models.IntegerField(default=0, primary_key=True)
timestamp = models.DateTimeField(default=timezone.now, db_index=True)
但是有几个问题:
即使 managed = False './manage.py makemigrations' 仍然会为此表创建迁移。 我什至试图将迁移留在那里,但用原始 SQL 替换模型以创建视图 但没有运气。
-
我现在需要做 select_related 来连接两个表和查询,但是我应该怎么做呢?
我在 SampleModel 上尝试了这样的外键:
by_date = models.ForeignKey(SampleModelWithMaxDate, null=True)
但这也行不通:
OperationalError: (1054, "Unknown column 'no_chain_sample_model_with_max_date.by_date_id' in 'field list'")
所以总的来说,我什至不确定这是否可能,我可以看到其他人正在使用带有视图的模型,并且只是为了查询对我也有用的独立模型,但有没有可能做比这更聪明的事情?
谢谢
【问题讨论】:
-
从您的问题中仍然不清楚您需要什么?给定顶部的 django 模型,您能否提供一个示例?
-
我只需要使用 Django ORM 翻译那个 SQL 查询。因此,如果没有指向自身的外键,在同一张表上加入似乎基本上是不可能的,我认为一个视图和另一个模型可以解决这个问题。但是我还没有真正看到有人使用基于数据库视图的数据库模型的任何示例,所以我想知道这是否可能。
-
没关系,但您期望的最终结果是什么。您想获取每个
user_id和最新timestamp的所有SampleModel实例吗? -
是的,你是对的,没有很清楚的解释谢谢
-
请检查我的回答。