Django GROUP BY包括不必要的列?

时间:2015-01-27 18:56:41

标签: django postgresql orm

我有Django代码如下

qs = Result.objects.only('time') qs = qs.filter(organisation_id=1) qs = qs.annotate(Count('id'))

它被翻译成以下SQL:

SELECT "myapp_result"."id", "myapp_result"."time", COUNT("myapp_result"."id") AS "id__count" FROM "myapp_result" WHERE "myapp_result"."organisation_id" = 1 GROUP BY "myapp_result"."id", "myapp_result"."organisation_id", "myapp_result"."subject_id", "myapp_result"."device_id", "myapp_result"."time", "myapp_result"."tester_id", "myapp_result"."data"

正如您所看到的,GROUP BY子句以我想要的字段(id)开头,但随后它继续列出所有其他字段。有什么方法可以说服Django不要像这样指定所有单独的字段吗?

正如您所看到的,即使使用.only('time')也无法阻止Django列出所有其他字段,但仅限于此GROUP BY子句。

我想这样做的原因是为了避免the issue described here,当涉及到JSON字段时,PostgreSQL不支持注释。我不想放弃本机JSON支持(因此我实际上并没有使用django-jsonfield)。如果我手动发出它而没有引用"myapp_result"."data"(模型上唯一的JSON字段),查询就可以正常工作。所以,如果我能说服Django不要参考它,我会没事的!

1 个答案:

答案 0 :(得分:2)

only仅推迟某些字段的加载,即它允许延迟加载大字段或未使用的字段。除非你确切知道自己在做什么以及为什么需要它,否则通常不应该使用它,因为它只不过是性能助推器而不是通常降低性能不当使用。

您正在寻找的是values()(或values_list()),它实际上排除了某些字段,而不仅仅是延迟加载。这将返回字典(或列表)而不是模型实例,但这是告诉Django不考虑其他字段的唯一方法:

qs = (Result.objects.filter_by(organisation_id=1)
            .values('time').annotate(Count('id')))