SqlAlchemy将SELECT子查询置于FROM子句触发GROUP BY报错如何解决
问题根因
- 你调用
.subquery()生成的是表子查询,作用是作为独立的表结构放到SQL的FROM子句中使用,当你直接把它传入主查询的query()参数列表时,SQLAlchemy会自动将其加入FROM子句,和主表生成笛卡尔积,完全不符合你要的SELECT子句里的关联标量子查询的需求。 - 当前生成的SQL里你相当于关联了两个完全独立的表,
anon_1.id是独立表的字段,自然需要被包含在GROUP BY子句中,这也是你触发psycopg2报错的直接原因。
修复方法
你需要将子查询转换为标量子查询,只要把.subquery()替换为.as_scalar()即可,这个方法会告诉SQLAlchemy该子查询只会返回单行单列的值,可以直接作为SELECT列表的字段使用,且会保留你写的关联主表别名的逻辑。
修改后的代码示例:
agreement = aliased(AgreementT) # 把.subquery()换成.as_scalar() subqueryActive = db_session.query(AgreementT.id).filter( (AgreementT.agreement_group_id == agreement.agreement_group_id), (AgreementT.active == 'Y') ).as_scalar() result = db_session.query( agreement.agreement_group_id, subqueryActive, # 其他你要查询的字段 ).filter(*filters) .group_by(agreement.agreement_group_id) .order_by(agreement.agreement_group_id) .all()
小提示:如果同个agreement_group_id下存在多个active='Y'的记录,标量子查询会返回多行报错,你可以根据业务需求在子查询中加
.limit(1)或者用func.max(AgreementT.id)这类聚合函数保证返回单行结果。
修改后生成的SQL就会和你预期的一致,子查询会放在SELECT子句中作为关联子查询执行,不会再出现额外的FROM子句子查询和GROUP BY报错。
内容的提问来源于stack exchange,提问作者gene b.
相关产品推荐
相关产品推荐

