如何在SQLAlchemy ORM中同时对多列执行IN过滤查询
高效实现PostgreSQL多列IN查询的SQLAlchemy ORM写法
当然有啦!针对PostgreSQL数据库,SQLAlchemy完全支持这种多列组合的IN查询,而且写法非常直接,能完美对应你熟悉的原生SQL逻辑,同时保证高效性。
核心实现方式
你可以使用SQLAlchemy提供的tuple_()函数来构建多列元组的IN条件,具体代码如下:
from sqlalchemy import tuple_ from your_models import Entity # 替换成你的实际模型导入路径 # 准备需要匹配的(name, entity_type)组合列表 target_pairs = [('abc', 'type1'), ('def', 'type2')] # 构建ORM查询 query = session.query(Entity).filter( tuple_(Entity.name, Entity.entity_type).in_(target_pairs) )
为什么这是高效的?
这个写法生成的SQL和你手动写的原生SQL几乎完全一致:
SELECT entities.id, entities.name, entities.entity_type FROM entities WHERE (entities.name, entities.entity_type) IN ((%s, %s), (%s, %s))
PostgreSQL对这种多列IN的语法优化非常成熟,所以性能和你直接执行原生SQL没有区别,完全不用担心额外的性能损耗。
兼容性补充
如果你使用的是SQLAlchemy 1.4及以上版本,其实还可以省略tuple_(),直接用模型列的元组来写:
query = session.query(Entity).filter( (Entity.name, Entity.entity_type).in_(target_pairs) )
不过为了兼容更早的SQLAlchemy版本,还是推荐使用tuple_()的写法,适配性更强。
不推荐的写法(对比参考)
有些同学可能会想到用or_结合多个and_来实现类似逻辑,比如:
from sqlalchemy import or_, and_ query = session.query(Entity).filter( or_( and_(Entity.name == 'abc', Entity.entity_type == 'type1'), and_(Entity.name == 'def', Entity.entity_type == 'type2') ) )
这种写法虽然能实现功能,但生成的SQL是多个OR条件的组合,当匹配的组合数量较多时,性能会比原生的多列IN差很多,而且代码也不够简洁,所以不推荐。
内容的提问来源于stack exchange,提问作者Mike Lynch
相关产品推荐
相关产品推荐

