如何避免SQLAlchemy使用except_时列名被自动添加前缀?
问题描述
我编写了如下查询语句:
query = included_query.except_(excluded_query)
其中included_query和excluded_query均针对TestModel模型进行查询。但将该查询转为子查询(即subquery = query.subquery())后,子查询的列名被添加了前缀(如subquery.c.test_models_id),而非TestModel的直接列名(如subquery.c.id)。
我尝试用with_entitites来获取正确列名,但这样返回的将不再是TestModel对象列表,而是列值元组。
请问如何在返回TestModel对象的同时,保留无前缀的正确列名?
相关未解决问题:SQLAlchemy:三张表union_all的子查询中列名带前缀
解决方法
方法1:用aliased将子查询映射回TestModel
通过aliased把带前缀列名的子查询重新关联到TestModel,既能保留对象结构,又能正常访问无前缀的列名:
from sqlalchemy.orm import aliased # 生成带前缀的子查询 subquery = query.subquery() # 将子查询映射为TestModel的别名 test_model_alias = aliased(TestModel, subquery) # 构建最终查询,返回TestModel对象 final_query = session.query(test_model_alias)
之后访问列直接用test_model_alias.id即可,无需前缀,且返回结果是TestModel对象。
方法2:创建子查询时显式指定列名
在生成子查询前,手动给每个列指定原始名称,覆盖自动生成的带前缀列名:
# 获取TestModel所有列,并重命名为原始列名 selected_columns = [getattr(TestModel, col).label(col) for col in TestModel.__table__.columns.keys()] # 重新构造查询,指定选择的列 query_with_alias = query.with_entities(*selected_columns) # 生成子查询,此时列名保持原始名称(如id) subquery = query_with_alias.subquery() # 从子查询映射回TestModel对象 final_query = session.query(TestModel).select_from(subquery)
这个方法通过label()强制列名不变,子查询列无前缀,最终返回TestModel对象列表。
方法3:使用from_self()替代subquery()
如果查询嵌套不复杂,直接用from_self()避免子查询列名前缀问题:
# 生成可直接映射的查询,返回TestModel对象 final_query = query.from_self()
from_self()会把原查询作为子查询,但自动处理列名映射,返回结果仍是TestModel对象,列名保持原始状态。
内容的提问来源于stack exchange,提问作者B T
相关产品推荐
相关产品推荐

