如何用直接SQL子查询过滤SQLAlchemy对象?实现单次查询执行
实现方法
你想要的单条SQL查询写法完全可以在SQLAlchemy中实现,下面提供两种可行方案:
方案1:直接使用text()原生SQL子查询
你的思路是对的,直接用text()包裹子查询语句就能生成符合要求的单条SQL,示例代码如下:
from sqlalchemy import text # 直接将子查询作为text对象传入filter query = MyModel.query.filter(MyModel.id == text(""" SELECT a.id FROM accounts a LEFT JOIN sessions s ON s.account_id = a.id LEFT JOIN suitable t ON t.session_id = s.id """))
执行该查询时,SQLAlchemy会生成你期望的单条SQL语句,仅执行一次数据库请求。注意:这种写法要求子查询必须返回单个值,否则会因=匹配多个结果报错;如果子查询可能返回多个id,需将==改为in_(),即MyModel.id.in_(text("..."))。
方案2:用SQLAlchemy ORM构造子查询(更推荐)
如果想避免直接写原生SQL字符串,可通过ORM的查询API构造子查询,示例如下(假设已定义Accounts、Sessions、Suitable三个声明式模型):
from sqlalchemy import select # 构造子查询,scalar_subquery()声明该查询返回单个标量值 subquery = select(Accounts.id)\ .outerjoin(Sessions, Sessions.account_id == Accounts.id)\ .outerjoin(Suitable, Suitable.session_id == Sessions.id)\ .scalar_subquery() # 关联子查询到主查询中 result = MyModel.query.filter(MyModel.id == subquery).all()
这种方式完全基于ORM语法,无需拼接SQL字符串,既提升了代码可维护性,也能避免潜在的SQL注入风险,生成的SQL语句和你要求的格式一致。
内容的提问来源于stack exchange,提问作者Cyril N.
相关产品推荐
相关产品推荐

