如何使用SQLAlchemy从admin、doctor、manager三张表中按email查询唯一用户记录
问题解决方案
你当前的多表查询写法默认生成笛卡尔积连接,多个filter是AND逻辑,要求三张表同时存在相同的email才会返回结果,和你要的OR查询逻辑完全不符,自然无法拿到正确结果。
可选实现方案
方案1:UNION ALL 一次查询(推荐)
通过合并三个子查询实现单次请求拿到结果,返回结果自带角色标识,适配后续业务逻辑:
from sqlalchemy import union_all def get_role_by_user_email(email): # 三个子查询返回字段结构保持一致,分别为:角色类型、id、用户名称、邮箱 admin_subq = session.query( "admin".label("role_type"), admin.id.label("id"), admin.name.label("user_name"), admin.email.label("email") ).filter(admin.email == email) doctor_subq = session.query( "doctor".label("role_type"), doctor.id.label("id"), doctor.doctorName.label("user_name"), doctor.email.label("email") ).filter(doctor.email == email) manager_subq = session.query( "manager".label("role_type"), manager.id.label("id"), manager.managerName.label("user_name"), manager.email.label("email") ).filter(manager.email == email) # 合并子查询,因email全局唯一,最多只会返回1条结果 union_query = union_all(admin_subq, doctor_subq, manager_subq).subquery() return session.query(union_query).first()
方案2:分表依次查询(写法更简单)
每个表的email字段有唯一索引,查询效率极高,可直接返回对应表的完整ORM对象:
def get_role_by_user_email(email): # 依次查询三张表,查到就返回,查不到返回None admin_record = session.query(admin).filter(admin.email == email).first() if admin_record: return {"role_type": "admin", "record": admin_record} doctor_record = session.query(doctor).filter(doctor.email == email).first() if doctor_record: return {"role_type": "doctor", "record": doctor_record} manager_record = session.query(manager).filter(manager.email == email).first() if manager_record: return {"role_type": "manager", "record": manager_record} return None
内容的提问来源于stack exchange,提问作者Saurabh
相关产品推荐
相关产品推荐

