英文:
How Can I Index an Array Produced by array_agg in Peewee
问题
我试图访问由PostgreSQL的array_agg创建的Peewee .select_from中包含的数组的第一个元素。
这是查询的简化版本:
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是一个公共交通工具,因为它是带有特定条件的Site表的精简版本。
这里返回的相关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以便使用[]进行索引。
英文:
I'm trying to access the first element of an array that is contained within a peewee .select_from and created by a postgresql array_agg.
Here is a simplified version of the query:
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())
Sites (ST) and locations (L) have a many-to-many relationship through an intermediary table LS. ST is a cte because it is a filtered down version of the Site table with certain criteria.
The relevant SQL being returned here is
SELECT (array_agg("ST"."sitename") = 1) AS "sitename"
Instead I want the sql to be
SELECT (array_agg("ST"."sitename"))[1] AS "sitename"
It seems that you can index into an ArrayField using [] from the Googling I did, but I'm assuming the result of fn.array_agg() isn't an ArrayField. I would like to know how to index into the results of an fn.array_agg(), or how to convert it into an ArrayField in order to index into it using [].
答案1
得分: 1
这是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
请注意,这是一段Python代码,对Peewee和Postgres的某些特定问题进行了处理。
英文:
This is annoyingly obtuse with Peewee at present - my apologies. Part of this is due to Postgres' insistence that the function be wrapped in parentheses before it can be indexed -- peewee tries to eliminate redundant parentheses, which forces an additional workaround. At any rate, here is one way:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论