如何在Peewee中索引array_agg生成的数组?
解决Peewee中PostgreSQL array_agg结果的数组索引问题
问题分析
你当前的代码中,直接对fn.array_agg()的结果使用[1]会被Peewee解析为等于操作(生成array_agg(...) = 1的SQL),这是因为fn.array_agg()返回的是Function对象,并非ArrayField,Peewee对普通Function对象的[]运算符重载逻辑是判断相等,而非数组索引。
两种可行解决方案
方案1:使用SQL表达式直接构造索引
通过SQL类直接拼接数组索引语法,让Peewee生成正确的PostgreSQL数组索引语句:
from peewee import SQL # 构造带索引的聚合表达式 agg_with_index = fn.array_agg(ST.c.sitename) + SQL('[1]') rows = list(ST.select_from(agg_with_index.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())
此方法会生成你期望的SQL:SELECT (array_agg("ST"."sitename"))[1] AS "sitename"
方案2:将聚合结果转换为ArrayField后索引
先通过Cast把array_agg的结果转换为对应类型的ArrayField,再使用[]索引:
from peewee import Cast, ArrayField, CharField # 将聚合结果转换为字符数组,再取第一个元素 agg_cast = Cast(fn.array_agg(ST.c.sitename), ArrayField(CharField())) rows = list(ST.select_from(agg_cast[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())
这种方式更符合Peewee的ORM类型系统,索引操作会被正确解析为PostgreSQL的数组下标访问。
内容的提问来源于stack exchange,提问作者NinjaMeTimbers
相关产品推荐
相关产品推荐

