SqlAlchemy中关联子查询时如何将子查询对象转为ResultProxy类?
解决方法:将子查询字段转为类式访问
我明白你的需求——现在查询返回的元组里,子查询的字段是裸值,没法像ORM对象那样用点语法访问,对吧?下面给你几个实用的方案,都是SQLAlchemy里常用的技巧:
方案1:利用SQLAlchemy的Row对象原生支持点语法
这是最省心的方法,只要给子查询的字段加上别名,查询返回的Row对象本身就支持用点语法访问字段值:
# 先给子查询的字段加别名(示例) subquery = session.query(OtherModel.id.label("sub_id")).filter(...).subquery() # 执行查询 query = session.query( ORM_Class, subquery.c.sub_id # 引用带别名的子查询字段 ).join(subquery, ORM_Class.id == subquery.c.id) results = query.all() for row in results: print(row[0].id) # 正常访问ORM对象的属性 print(row.sub_id) # 直接用点语法访问子查询的字段值!
方案2:用Bundle包装子查询字段
如果子查询有多个字段,想把它们打包成一个类似对象的结构统一访问,可以用SQLAlchemy的Bundle类:
from sqlalchemy import Bundle # 定义包含多个字段的子查询 subquery = session.query( OtherModel.id.label("sub_id"), OtherModel.name.label("sub_name") ).filter(...).subquery() # 用Bundle打包子查询字段 query = session.query( ORM_Class, Bundle("sub_data", subquery.c.sub_id, subquery.c.sub_name) ).join(subquery, ORM_Class.id == subquery.c.id) results = query.all() for orm_obj, sub_data in results: print(orm_obj.id) print(sub_data.sub_id) # 类式访问子查询的id print(sub_data.sub_name) # 类式访问子查询的name
方案3:自定义数据结构包装结果
如果需要更灵活的结构,可以用Python的namedtuple或dataclasses把整个查询结果包装成统一的对象,方便后续代码的可读性:
用namedtuple的示例:
from collections import namedtuple # 定义命名元组类型 QueryResult = namedtuple("QueryResult", ["orm_obj", "sub_id", "sub_name"]) # 执行查询并转换结果 raw_results = session.query( ORM_Class, subquery.c.sub_id, subquery.c.sub_name ).join(...).all() results = [QueryResult(*row) for row in raw_results] # 访问方式 for res in results: print(res.orm_obj.id) print(res.sub_id) print(res.sub_name)
用dataclasses的示例(Python 3.7+):
from dataclasses import dataclass @dataclass class QueryResult: orm_obj: ORM_Class sub_id: int sub_name: str # 转换结果 results = [QueryResult(*row) for row in raw_results] # 访问方式和上面完全一致
内容的提问来源于stack exchange,提问作者mad_
相关产品推荐
相关产品推荐

