如何在SQLAlchemy继承加载时仅过滤单个子类并对Union应用order_by
在SQLAlchemy中过滤单个子类并处理Union结果排序
没问题,这两种需求场景都能在SQLAlchemy里轻松实现,我分两种常见情况给你拆解:
场景1:获取过滤后的Engineer + 全部Manager,合并后排序
如果你的需求是拿到所有符合条件的Engineer,加上所有未过滤的Manager,然后合并结果并统一排序,可以这么做:
from sqlalchemy import union_all from sqlalchemy.orm import with_polymorphic # 1. 构造带过滤条件的Engineer查询 engineer_subset = with_polymorphic(Employee, Engineer, aliased=True) engineer_query = s.query(engineer_subset).filter( engineer_subset.Engineer.department == "Backend" # 这里只针对Engineer子类过滤 ) # 2. 构造无过滤的Manager查询 manager_full = with_polymorphic(Employee, Manager, aliased=True) manager_query = s.query(manager_full) # 3. 合并两个查询(用union_all保留重复,用union则去重) combined_subquery = union_all( engineer_query.subquery(), manager_query.subquery() ).select() # 4. 基于合并后的结果查询Employee实例,并添加排序 final_query = s.query(Employee).from_statement(combined_subquery).order_by(Employee.id) # 执行查询 results = final_query.all()
这里的核心是用with_polymorphic分别针对两个子类构造查询,只给Engineer加上过滤条件,再通过union_all合并结果,最后在顶层查询上应用order_by。
场景2:关联查询中仅过滤Engineer,Manager不受影响
如果是像你示例里的关联查询场景,只想过滤参与关联的Engineer,而Manager的数据完全不受过滤条件影响,可以直接在filter里指定Engineer别名的子类字段:
from sqlalchemy import and_ from sqlalchemy.orm import with_polymorphic engineer_employee = with_polymorphic(Employee, [Engineer], aliased=True) manager_employee = with_polymorphic(Employee, [Manager], aliased=True) # 仅对Engineer添加过滤条件,Manager的关联逻辑不受影响 q = s.query(engineer_employee, manager_employee).\ join(manager_employee, and_( engineer_employee.id > manager_employee.id, engineer_employee.name == manager_employee.name )).\ filter(engineer_employee.Engineer.salary > 100000) # 只过滤Engineer的薪资条件 # 如果需要排序,直接在查询链末尾添加order_by q = q.order_by(engineer_employee.id, manager_employee.name) q.all()
这个写法里,过滤条件只作用于engineer_employee这个别名对应的Engineer子类数据,Manager的部分依然会按照关联条件全部参与查询,不会被过滤。
内容的提问来源于stack exchange,提问作者Fateh Mohamed
相关产品推荐
相关产品推荐

