You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 15:06:03