postgresql 如何索引Peewee中array_agg生成的数组

vhmi4jdf  于 2023-02-15  发布在  PostgreSQL
关注(0)|答案(1)|浏览(150)

我正在尝试访问一个数组的第一个元素,该数组包含在peewee.select_from中,并由postgresql array_agg创建。
下面是该查询的简化版本:

rows = list(ST.select_from(fn.array_agg(ST.c.sitename)[1].alias("sitename"))
 .join(LS, on=ST.c.id == LS.site)
 .join(L, on=LS.location == L.id)
 .group_by(L).with_cte(ST).objects().dicts())

站点(ST)和位置(L)通过中间表LS具有多对多的关系。ST是cte,因为它是站点表的具有特定标准的向下过滤版本。
此处返回的相关SQL为

SELECT (array_agg("ST"."sitename") = 1) AS "sitename"

相反,我希望sql是

SELECT (array_agg("ST"."sitename"))[1] AS "sitename"

从我搜索的结果来看,似乎可以使用[]索引到ArrayField,但我假设fn.array_agg()的结果不是ArrayField。我想知道如何索引到fn.array_agg()的结果,或者如何将其转换为ArrayField,以便使用[]索引到它。

lsmepo6l

lsmepo6l1#

这对于Peewee来说是非常愚蠢的--我道歉。部分原因是Postgres坚持在索引之前 * 用括号将函数括起来-- Peewee试图消除多余的括号,这就需要一个额外的解决方案。无论如何,这里有一个方法:

p1, p2, p3 = [Post.create(content='p%s' % i) for i in '123']
Comment.create(post=p1, comment='p1-c1')
Comment.create(post=p1, comment='p1-c2')
Comment.create(post=p2, comment='p2-c1')

idx = NodeList([
    SQL('(array_agg('),
    Comment.comment,
    SQL('))[%s]', (1,))])

query = (Post
         .select(Post, idx.alias('comment'))
         .join(Comment, JOIN.LEFT_OUTER)
         .group_by(Post)
         .order_by(Post.content))
# p1 p1-c1
# p2 p2-c1
# p3 None

相关问题