Return Django ORM 子查询中的多个值
Return multiple values in Subquery in Django ORM
问题是关于 Django ORM 中的 Subquery
和 ArrayAgg
。
例如,我有 2 个模型,彼此之间没有任何关系:
class Example1(models.Model):
ident = Integerfield()
class Example2(models.Model):
ident = IntegerField()
email = EmailField()
FK、M2M、O2O这2个模式之间没有联系,但是现场
ident
在两个模型中可能是相同的整数(这在某种程度上是一种联系)并且通常对于 Example1
的 1 个实例, Example2
的多个实例具有相同的 ident
.
我想制作一个 subquery
或 arrayagg
(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')
)
)
问题是关于 Django ORM 中的 Subquery
和 ArrayAgg
。
例如,我有 2 个模型,彼此之间没有任何关系:
class Example1(models.Model):
ident = Integerfield()
class Example2(models.Model):
ident = IntegerField()
email = EmailField()
FK、M2M、O2O这2个模式之间没有联系,但是现场
ident
在两个模型中可能是相同的整数(这在某种程度上是一种联系)并且通常对于 Example1
的 1 个实例, Example2
的多个实例具有相同的 ident
.
我想制作一个 subquery
或 arrayagg
(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')
)
)