我在几乎相同的模型和mysql表上有两个不同的查询,但由于某种原因,其中一个工作正常,另一个总是选择推迟DateTime字段,导致它在以后尝试访问时执行数千个其他查询数据。在我看来,这两个电话是:
sent_messages = list(SentMessage.objects.by_tags_and_profile(tags, profiles, start_date, end_date))
received_messages = list(ReceivedMessage.objects.by_tags_and_sources(tags, sources, start_date, end_date))
第一个工作正常,但第二个作为ReceivedMessage_Deferred_date
相关模型是:
class ReceivedMessage(models.Model):
_db = "received_message"
msg_id = models.CharField(max_length=128)
date = models.DateTimeField(db_column="created_date")
tag = models.IntegerField()
source = models.IntegerField()
objects = ReceivedMessageManager
class Meta:
db_table = u'received_message'
ordering = ['-date']
unique_together = ('source', 'msg_id', 'tag')
class ReceivedMessageManager
def by_tags_and_sources(self, tags, sources, since=None, before=None):
sql = """SELECT *
FROM received_message rm
WHERE rm.tag IN (%s) AND rm.source IN (%S)
"""
params = [tags, sources]
if since:
sql += ' AND rm.created_date > %s '
params.append(since)
if before:
sql += ' AND rm.created_date < %s '
params.append(before)
return self.raw(*safe_sql(sql, *params))
SentMessage和SentMessageManager类几乎完全相同,只是将“source”替换为“profile”并在模型更改中
date = models.DateTimeField(db_column="created_date")
到
created_date = models.DateTimeField()
我怀疑,推迟date / created_date字段的ReceivedMessage与模型变量名称的关系与数据库字段名称不匹配,就像它对SentMessage一样,但即使这样,我也不确定如何使其工作(这是一个庞大系统的一部分,改变这些名称是一项巨大的工作,我们希望避免这些风险。)
附加说明:我知道通过查询这个基本的我可以很容易地使用ReceivedMessage.objects.filter(...)
并且事实上已经解决了问题,但我们有意识地决定将查询逻辑保留在那个管理器类中如果任何字段或索引发生变化,我们就不必在我们查询的代码库中的任何地方搜索,以便更改它。
答案 0 :(得分:0)
当你select FIELD_NAMES...
select created_date
查询时,你偶然发现select created_date AS date
不确定这是否是有效的SQL,但你明白了。
我认为当ORM将原始查询的结果加载回python对象时,它希望所选的字段与模型名称完全对齐。 https://docs.djangoproject.com/es/1.9/topics/db/sql/#mapping-query-fields-to-model-fields有一些细节。