无外键时如何用SQLAlchemy Session实现A表特定条件查询?
解决方法:SQLAlchemy查询满足条件的A表text字段
嘿,这个需求其实很好实现,用SQLAlchemy的左外连接或者子查询都能搞定,我给你两种实用的写法,都是基于Session来操作的:
方法1:左外连接(LEFT JOIN)+ 条件筛选
这种方式最直观,把A表和B表按common字段做左连接,然后筛选出两种符合要求的情况:要么B表没有匹配的记录,要么匹配到的B表记录url为None。
from sqlalchemy import select, or_ # 构建查询语句 query = select(A.text).outerjoin(B, A.common == B.common).where( or_( B.id.is_(None), # A的common值在B表中无对应项 B.url.is_(None) # 对应B表记录的url为None ) ) # 执行查询并获取所有结果 result = session.execute(query).scalars().all()
解释一下:outerjoin会保留A表的所有记录,匹配不到B表的记录时,B表的字段都会是NULL,所以用B.id.is_(None)就能判断没有对应项;同时加上B.url.is_(None)的条件,就能覆盖两种需求场景。
方法2:子查询排除不符合条件的记录
我们也可以先找出那些在B表中存在对应记录且url不为None的common值,然后筛选A表中不在这个集合里的记录,这样也能达到需求的效果:
from sqlalchemy import select, not_, exists, and_ # 子查询:获取B表中url不为空的common值集合 valid_b_common = select(B.common).where(B.url.isnot(None)) # 主查询:筛选A表中满足条件的记录 query = select(A.text).where( or_( # A的common不在B表有有效url的集合里(要么无对应,要么对应url为空) not_(A.common.in_(valid_b_common)), # 额外用exists确保存在对应B记录且url为None的情况(和上面条件互补,也可以合并) exists().where(and_(B.common == A.common, B.url.is_(None))) ) ) result = session.execute(query).scalars().all()
这种方式更偏向于反向排除,适合对SQL子查询比较熟悉的场景。
注意点
因为两张表没有定义外键关联,所以在做连接或者子查询的时候,必须手动指定关联条件A.common == B.common,这是不要遗漏的关键步骤。
内容的提问来源于stack exchange,提问作者PapeK24
相关产品推荐
相关产品推荐

