You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么SQLAlchemy 1.4查询结果字典会忽略text()构造的列?

问题原因

你直接在sa.text()的SQL语句中写的as graphs别名仅在数据库执行层面生效,SQLAlchemy的结果解析逻辑不会自动从原生SQL片段中提取别名作为结果列的键,所以才会出现结果有值但keys()里没有对应列名的情况。

解决方法

有两种常用方案都可以满足你在PostgreSQL侧执行聚合的要求:

方案1(推荐):使用SQLAlchemy原生函数构造聚合逻辑

完全不用写原生SQL片段,通过sa.func调用PG的jsonb_agg函数,显式设置列标签:

stmt = sa.select(
    Quadrant.id,
    sa.func.jsonb_agg(Graph.data, order_by=Graph.id).label("graphs")
).outerjoin(
    Graph, Quadrant.id == Graph.quadrant_id
).group_by(
    Quadrant.id
)

这种写法完全符合SQLAlchemy 1.4/2.0的语法规范,ORM可以自动识别列名,不需要硬编码SQL片段,后续维护更方便。

方案2:给原生SQL片段显式设置标签

如果你的聚合逻辑特别复杂,必须写原生SQL片段,可以用sa.literal_column()包裹SQL片段后调用label()方法设置列名:

stmt = sa.select(
    Quadrant.id,
    sa.literal_column("jsonb_agg(graph.data order by graph.id)").label("graphs")
).outerjoin(
    Graph, Quadrant.id == Graph.quadrant_id
).group_by(
    Quadrant.id
)

可选优化

如果需要直接拿到字典格式的结果,可以在执行查询时调用mappings()方法,不需要自己再做转换:

with dbsession.begin():
    res = dbsession.execute(stmt).mappings()
    for r in res:
        print(r.keys()) # 输出 ['id', 'graphs']
        print(r['graphs']) # 直接按键取值

内容的提问来源于stack exchange,提问作者marcogh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.22 02:45:04