Django与Postgresql,列必须出现在GROUP BY子句中或用于聚合函数。

7
我正在使用Django 1.11和Postgresql 9.6。 在我的应用中,有一个名为Person的模型,它有几个字段。在数据库中,它是一个物化视图。
class Person(models.Model):
    personid = models.CharField(max_length=18, primary_key=True)
    count = models.BigIntegerField()
    native = models.CharField(max_length=2)
    ...

当执行时

persons = Person.objects.values('personid', 'native')\
    .annotate(total=Count('native'))

它指出 psycopg2.ProgrammingError: column "person.native" must appear in the GROUP BY clause or be used in an aggregate function

只有当选择一个列未将personid设置为主键未执行annotate操作时,它才不会出现错误。

我打印查询SQL:

SELECT
"person"."native",
"person"."personid",
COUNT("person"."native") AS "total"
FROM "person"
GROUP BY "person"."native", "person"."personid"

我该怎么做?

我将视图转换为表格,并将personid设置为主键,然后就没有问题了。


如果您在psql shell(或任何其他允许您直接发出查询的界面)中尝试此查询,而没有使用Django或Python,会发生什么? - W.Mann
在psql shell中它可以工作,所以我不知道为什么。 - imcmy
你能排除Django发送到数据库的SQL与它打印的不同吗? - W.Mann
是的,我打印并执行它。 - imcmy
personid 是主键。如果您按此字段分组,它不会产生任何影响。 - alfonso.kim
2个回答

9
这是Django >= 1.8 和 Django < 2.0中已知的一个错误。在Django 2.0中已经修复了此问题。我曾经遇到过同样的问题并在django-users邮件列表中提出了这个问题。
发生的情况是Django进行了一些优化,特别是基于PostgreSQL。在PostgreSQL中,你只需要在GROUP BY子句中使用pk列,但这仅适用于表。(如果这样做,查询会更快)。在PostgreSQL中,你不能在视图中有一个PK,这就是为什么我们使用未管理的模型与后端视图耦合时会出现问题的原因。
参考资料:

0

我的 Django 版本是 2.2.10。
我遇到了问题并解决了它。
你应该在 ORM 后面添加 .order_by("xxx")

之前(错误信息为 必须出现在 GROUP BY 子句中):

search_models.Author.objects.values("first_institution", 'institution_code').annotate(counts=Count('first_institution'))

之后(固定):

search_models.Author.objects.values("first_institution", 'institution_code').annotate(counts=Count('first_institution')).order_by('-counts')

这对我有用,也希望能帮到你。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接