【问题标题】:Why does Django ORM add a not specified field in the GROUP BY clause为什么 Django ORM 在 GROUP BY 子句中添加一个未指定的字段
【发布时间】:2019-10-30 10:26:26
【问题描述】:

我想用 ORM 执行这个查询:

SELECT ARRAY_AGG("wcm_workflows_transition"."name") AS "names"
FROM "wcm_workflows_transition"
GROUP BY "wcm_workflows_transition"."workflow_id"
ORDER BY "wcm_workflows_transition"."name" ASC;

为此,我使用

Transition.objects.values("workflow__id").annotate(names=ArrayAgg("name")).values("names")

但由于一些未知的原因,Django 在GROUP BY 子句中添加了"wcm_workflows_transition"."name"
所以前面的 Django ORM 表达式执行的查询是:

SELECT ARRAY_AGG("wcm_workflows_transition"."name") AS "names"
FROM "wcm_workflows_transition"
GROUP BY "wcm_workflows_transition"."workflow_id", "wcm_workflows_transition"."name"
ORDER BY "wcm_workflows_transition"."name" ASC;

我不能使用aggregate,因为我想在子查询中使用查询集。
以下是模型(简化)

class Workflow:
    name = models.CharField(_(u'Name'), max_length=100, unique=True, db_index=True)


class Transition(models.Model):
    name = models.CharField(_(u'Name'), max_length=100, db_index=True)
    workflow = models.ForeignKey(Workflow, verbose_name=_(u'Workflow'), related_name='transitions',
            db_index=True, on_delete=models.PROTECT)

    class Meta:
        ordering = ('name', )

现在我有两个问题:

  1. 为什么 Django ORM 将此字段添加到 GROUP BY 子句中?
  2. 如何使用 ORM 执行预期的查询

我尝试过的:

我以为 Django 在 GROUP BY 中添加了注解中使用的所有字段,所以我更改了聚合字段但没有更改按字段分组。
然后我问自己name 字段是否有任何限制。事实上,它具有db_index=True 约束。所以我用一个不受约束的字段更改了聚合字段,但 name 仍在 GROUP BY

【问题讨论】:

    标签: python sql django orm


    【解决方案1】:

    为什么 Django ORM 将此字段添加到 GROUP BY 子句中?

    因为添加的字段是默认的ORDER BY字段。
    您可以在 Transition 模型的 Meta 类中看到这一点:ordering = ('name', )

    如何使用 ORM 执行预期的查询?

    order_by() 添加到您的查询中以清除所有默认值。 它是这样的:

    Transition.objects.order_by().values("workflow__id").annotate(names=ArrayAgg("label")).values("names")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-04
      • 2011-02-16
      • 2023-04-04
      • 2020-05-02
      • 2021-08-01
      • 2019-02-28
      • 2013-08-29
      • 1970-01-01
      相关资源
      最近更新 更多