为什么Django ORM在groupby claus中添加一个未指定的字段

2024-05-14 14:25:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我想用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,因为我想在子查询中使用queryset。
以下是模型(简化)

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


Tags: djangonameidtruedbindexbynames
1条回答
网友
1楼 · 发布于 2024-05-14 14:25:18

为什么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")

相关问题 更多 >

    热门问题