简体   繁体   English

在 Django 中使用具有多个结果的子查询进行注释

[英]Annotation with a subquery with multiple result in Django

I use postgresql database in my project and I use below example from django documentation .我在我的项目中使用 postgresql 数据库,并使用 django 文档中的以下示例。

from django.db.models import OuterRef, Subquery
newest = Comment.objects.filter(post=OuterRef('pk')).order_by('-created_at')
Post.objects.annotate(newest_commenter_email=Subquery(newest.values('email')[:1]))

but instead of newest commenter email, i need last two commenters emails.但不是最新的评论者 email,我需要最后两封评论者的电子邮件。 i changed [:1] to [:2] but this exception raised: ProgrammingError: more than one row returned by a subquery used as an expression .我将[:1]更改为[:2]但引发了此异常: ProgrammingError: more than one row returned by a subquery used as an expression

You'll need to aggregate the subquery results in some way: perhaps by using an ARRAY() construct.您需要以某种方式聚合子查询结果:也许通过使用ARRAY()构造。

You can create a subclass of Subquery to do this:您可以创建Subquery的子类来执行此操作:

class Array(Subquery):
    template = 'ARRAY(%(subquery)s)`
    output_field = ArrayField(base_field=models.TextField())

(You can do a more automatic method of getting the output field, but this should work for you for now: see https://schinckel.net/2019/07/30/subquery-and-subclasses/ for more details). (您可以使用更自动的方法来获取 output 字段,但这现在应该对您有用:请参阅https://schinckel.net/2019/07/30/subquery-and-subclasses/了解更多详细信息)。

Then you can use:然后你可以使用:

posts = Post.objects.annotate(
    newest_commenters=Array(newest.values('email')[:2]),
)

The reason this is happening is because a correlated subquery in postgres may only return one row, with one column.发生这种情况的原因是因为 postgres 中的相关子查询可能只返回一行,一列。 You can use this mechanism to deal with multiple rows, and perhaps use JSONB construction if you need multiple columns.您可以使用这种机制来处理多行,如果您需要多列,也许可以使用 JSONB 构造。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM