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

Posted

技术标签:

【中文标题】Django 与 Postgresql,列必须出现在 GROUP BY 子句中或在聚合函数中使用【英文标题】:Django with Postgresql, column must appear in the GROUP BY clause or be used in an aggregate function 【发布时间】:2017-06-16 08:32:36 【问题描述】:

我正在使用 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为主键不执行注释时不会报错。

我打印查询sql:

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

我能做什么?

我把view做成table,把personid设置为主键,就没有问题了。

【问题讨论】:

当您在psql shell(或任何其他让您直接发出查询的界面)中尝试此查询时会发生什么? 在 psql shell 中,它可以工作。所以我不知道为什么。 你能排除 Django 发送的 SQL 不是它打印到数据库的 SQL 吗? 是的,我打印并执行。 personid 是主键。如果按此字段分组,则不会有任何影响。 【参考方案1】:

这是 Django >= 1.8 和 Django

发生的事情是 Django 执行了一些优化,尤其是基于 PostgreSQL。在 PostgreSQL 中,您只需要在 GROUP BY 子句中使用 pk 列,但这仅适用于表。 (如果这样做,查询会运行得更快。)在 PostgreSQL 的视图中不能有 PK,这就是为什么这对我们来说是个问题,因为我们在后端使用非托管模型和视图。

参考资料:

https://github.com/django/django/commit/daf2bd3efe53cbfc1c9fd00222b8315708023792 https://groups.google.com/forum/#!topic/django-developers/lx3ZSq-W9X4 https://groups.google.com/d/msg/django-developers/lx3ZSq-W9X4/yh4I2CsoBwAJ https://code.djangoproject.com/ticket/28107

【讨论】:

【参考方案2】:

我的 django 版本是 2.2.10。 我遇到了问题,我解决了。 你应该添加.order_by("xxx") 按照你的ORM!

之前must appear in the GROUP BY clause 出错):

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')

它对我有用,也希望可以帮助你。

【讨论】:

以上是关于Django 与 Postgresql,列必须出现在 GROUP BY 子句中或在聚合函数中使用的主要内容,如果未能解决你的问题,请参考以下文章

Postgresql“列必须出现在 GROUP BY 子句中或在聚合函数中使用”和唯一字段

必须出现在 postgresql 的 GROUP BY 子句中

PostgreSQL SQL 语句生成自定义 blob 存储表

按 PostgreSQL 中的指定列分组

PostgreSQL - 如何保持列更新

错误:分布式表的唯一索引必须包含散列分布列。啥时候从 postgresql 迁移到 postgresql-xl