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 子句中