0

我在我的项目中使用 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]))

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

4

1 回答 1

7

您需要以某种方式聚合子查询结果:也许通过使用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 构造。

于 2020-07-31T04:36:08.470 回答