【问题标题】:Annotation with a subquery with multiple result in Django在 Django 中使用具有多个结果的子查询进行注释
【发布时间】:2020-09-06 21:44:14
【问题描述】:

我在我的项目中使用 postgresql 数据库,并使用来自 django documentation 的以下示例。

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]))

但我需要最后两封评论者电子邮件,而不是最新的评论者电子邮件。我将 [:1] 更改为 [:2] 但引发了此异常:ProgrammingError: more than one row returned by a subquery used as an expression

【问题讨论】:

    标签: django django-orm django-postgresql django-annotate django-subquery


    【解决方案1】:

    您需要以某种方式聚合子查询结果:可能使用ARRAY() 构造。

    您可以创建Subquery 的子类来执行此操作:

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

    (您可以使用更自动的方法来获取输出字段,但现在这应该对您有用:请参阅https://schinckel.net/2019/07/30/subquery-and-subclasses/ 了解更多详细信息)。

    那么你可以使用:

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

    发生这种情况的原因是因为 postgres 中的相关子查询可能只返回一行一列。您可以使用这种机制来处理多行,如果您需要多列,也许可以使用 JSONB 构造。

    【讨论】:

      猜你喜欢
      • 2014-12-22
      • 2018-08-26
      • 1970-01-01
      • 1970-01-01
      • 2021-07-12
      • 2019-12-30
      • 2015-09-03
      • 2020-07-04
      • 2020-07-09
      相关资源
      最近更新 更多