Return Django ORM 子查询中的多个值

Return multiple values in Subquery in Django ORM

问题是关于 Django ORM 中的 SubqueryArrayAgg

例如,我有 2 个模型,彼此之间没有任何关系:


class Example1(models.Model):
    ident = Integerfield()

class Example2(models.Model):
    ident = IntegerField()
    email = EmailField()

FK、M2M、O2O这2个模式之间没有联系,但是现场 ident 在两个模型中可能是相同的整数(这在某种程度上是一种联系)并且通常对于 Example1 的 1 个实例, Example2 的多个实例具有相同的 ident .

我想制作一个 subqueryarrayagg (db Postgres) 或 RAWSQL 之外的任何方式来制作这样的注释:

Example1.objects.annotate(
cls2=Subquery(
Example2.objects.filter(
ident=OuterRef(‘ident’
).values_list(‘email’, flat=True).

#or

Example1.objects.annotate(
cls2=StringAgg(
something here???, 
delimeter=’, ‘,
 distinct=True,)

确定这在 Subquery returns 多行时不起作用并且似乎无法使用 StringAgg 因为我们在模型之间没有任何联系(没有东西可以放在里面StringAgg).

关于如何在一个查询集中使用来自 Example2 的电子邮件注释 Example1 有什么想法吗?

这将在 CASE 表达式中使用。

谢谢...

对于MySQL后端,你可以使用django-mysql, or take a look on the post的GroupConcat自己做一个聚合函数:

from django_mysql.models import GroupConcat
Example1.objects.annotate(
    cls2=Subquery(
        Example2.objects.filter(ident=OuterRef('ident')).values('ident')\
        .annotate(emails=GroupConcat('email')).values('emails')
    )
)

对于 PostgreSQL 后端,您可以使用 ArrayAgg or StringAgg:

from django.contrib.postgres.aggregates import ArrayAgg, StringAgg
Example1.objects.annotate(
    cls2=Subquery(
        Example2.objects.filter(ident=OuterRef('ident')).values('ident')\
        .annotate(emails=ArrayAgg('email')).values('emails')
    )
)
# or
Example1.objects.annotate(
    cls2=Subquery(
        Example2.objects.filter(ident=OuterRef('ident')).values('ident')\
        .annotate(emails=StringAgg('email', ',')).values('emails')
    )
)