SQLAlchemy 2.0查询中使用defer/load_only的实现方法(无需在列定义加deferred)
SQLAlchemy 2.0 查询阶段控制列加载的方法
核心结论
完全可以在查询阶段直接使用defer()、load_only()方法控制字段加载,不需要提前在模型列定义中标记deferred()。
注意事项
你示例代码中的写法有一点问题:SQLAlchemy 2.0中所有列加载策略都需要通过select对象的.options()方法传入,不能直接链式调用defer()。
具体实现方法
首先需要从sqlalchemy.orm导入对应的加载策略方法:
from sqlalchemy.orm import defer, load_only
1. 用defer()排除指定列(匹配你的需求)
执行查询时不会加载acl字段,只有后续主动访问实例的acl属性时,才会触发懒加载查询该字段:
stmt = select(Signals).join(Signals.value_types).options( defer(Signals.acl) ) async with Session(engine) as session: result = await session.execute(stmt) signals_instances = result.scalars().all()
如果需要用列名的字符串形式指定,可以补充of_type参数明确所属模型:
.options(defer("acl", of_type=Signals))
2. 用load_only()仅加载指定列
如果只需要加载少数几个字段,用load_only()写法更简洁:
# 仅加载id、value_type_id两个字段,其余字段访问都会触发懒加载 stmt = select(Signals).join(Signals.value_types).options( load_only(Signals.id, Signals.value_type_id) )
3. 无懒加载的字段过滤方案
如果不需要返回模型实例,也不需要懒加载能力,可以直接在select中明确列出需要查询的字段,返回结果为行元组:
stmt = select(Signals.id, Signals.value_type_id, Signals.sources_id).join(Signals.value_types)
4. 关联表的列加载控制
如果需要同时控制关联表的加载字段,可以嵌套加载策略:
from sqlalchemy.orm import joinedload # 排除Signals的acl字段,同时排除关联表value_types的content大字段 stmt = select(Signals).options( defer(Signals.acl), joinedload(Signals.value_types).defer(ValueTypes.content) )
内容的提问来源于stack exchange,提问作者Who Cares
相关产品推荐
相关产品推荐

