SqlAlchemy 2.0 中文文档(十九)(4)https://developer.aliyun.com/article/1562934
通配符加载策略
每个joinedload()
、subqueryload()
、lazyload()
、selectinload()
、noload()
和raiseload()
都可以用于设置特定查询的relationship()
加载的默认样式,影响所有未在语句中另行指定的relationship()
-映射属性。通过将字符串'*'
作为这些选项中的任何一个的参数传递,可以使用此功能:
from sqlalchemy import select from sqlalchemy.orm import lazyload stmt = select(MyClass).options(lazyload("*"))
在上面,lazyload('*')
选项将取代所有正在使用的relationship()
构造的lazy
设置,但不包括那些使用lazy='write_only'
或lazy='dynamic'
的情况。
如果某些关系指定了 lazy='joined'
或 lazy='selectin'
,例如,使用 lazyload('*')
将单方面导致所有这些关系使用 'select'
加载,例如,当访问每个属性时发出一个 SELECT 语句。
该选项不会取代查询中指定的加载选项,例如joinedload()
,selectinload()
等。下面的查询仍将对widget
关系使用连接加载:
from sqlalchemy import select from sqlalchemy.orm import lazyload from sqlalchemy.orm import joinedload stmt = select(MyClass).options(lazyload("*"), joinedload(MyClass.widget))
不管joinedload()
指令出现在lazyload()
选项之前还是之后,如果传递了包含 "*"
的多个选项,则最后一个选项将生效。
每个实体的通配符加载策略
通配符加载策略的变体是能够按实体基础设置策略的能力。例如,如果查询User
和Address
,我们可以指示Address
上的所有关系使用延迟加载,同时通过首先应用Load
对象,然后将 *
指定为链接选项:
from sqlalchemy import select from sqlalchemy.orm import Load stmt = select(User, Address).options(Load(Address).lazyload("*"))
上述,Address
上的所有关系都将设置为延迟加载。### 每个实体的通配符加载策略
通配符加载策略的变体是能够按实体基础设置策略的能力。例如,如果查询User
和Address
,我们可以指示Address
上的所有关系使用延迟加载,同时通过首先应用Load
对象,然后将 *
指定为链接选项:
from sqlalchemy import select from sqlalchemy.orm import Load stmt = select(User, Address).options(Load(Address).lazyload("*"))
上述,Address
上的所有关系都将设置为延迟加载。
将显式连接/语句路由到急加载集合
joinedload()
的行为是自动创建连接,使用匿名别名作为目标,其结果路由到加载对象上的集合和标量引用。通常情况下,查询已经包含了表示特定集合或标量引用的必要连接,而由 joinedload 功能添加的连接是多余的 - 但您仍希望填充集合/引用。
对于此,SQLAlchemy 提供了 contains_eager()
选项。该选项的使用方式与 joinedload()
选项相同,只是假定 Select
对象将明确包括适当的连接,通常使用 Select.join()
等方法。下面,我们指定了 User
和 Address
之间的连接,并额外将其作为 User.addresses
的急切加载的基础:
from sqlalchemy.orm import contains_eager stmt = select(User).join(User.addresses).options(contains_eager(User.addresses))
如果语句的“急切”部分是“别名”,则应使用 PropComparator.of_type()
指定路径,这允许传递特定的 aliased()
构造:
# use an alias of the Address entity adalias = aliased(Address) # construct a statement which expects the "addresses" results stmt = ( select(User) .outerjoin(User.addresses.of_type(adalias)) .options(contains_eager(User.addresses.of_type(adalias))) ) # get results normally r = session.scalars(stmt).unique().all() SELECT users.user_id AS users_user_id, users.user_name AS users_user_name, adalias.address_id AS adalias_address_id, adalias.user_id AS adalias_user_id, adalias.email_address AS adalias_email_address, (...other columns...) FROM users LEFT OUTER JOIN email_addresses AS email_addresses_1 ON users.user_id = email_addresses_1.user_id
作为参数给出的路径必须是从起始实体开始的完整路径,例如,如果我们正在加载 Users->orders->Order->items->Item
,则选项将如下使用:
stmt = select(User).options(contains_eager(User.orders).contains_eager(Order.items))
使用 contains_eager()
来加载自定义过滤的集合结果。
当我们使用 contains_eager()
时,我们是自己构造将用于填充集合的 SQL。由此自然而然地,我们可以选择 修改 集合意图存储的值,通过编写我们的 SQL 来加载集合或标量属性的元素子集。
提示
SQLAlchemy 现在有了一个 更简单的方法 来实现这一点,即允许将 WHERE 条件直接添加到加载器选项,如 joinedload()
和 selectinload()
使用 PropComparator.and_()
。参见 Adding Criteria to loader options 章节中的示例。
如果相关的集合要使用比简单的 WHERE 子句更复杂的 SQL 条件或修饰符进行查询,这里描述的技术仍然适用。
举例来说,我们可以加载一个User
对象,并仅急切地加载其中特定的地址到其.addresses
集合中,方法是通过过滤连接的数据,并使用 contains_eager()
路由它,同时还使用 Populate Existing 确保任何已加载的集合都被覆盖:
stmt = ( select(User) .join(User.addresses) .filter(Address.email_address.like("%@aol.com")) .options(contains_eager(User.addresses)) .execution_options(populate_existing=True) )
上面的查询将仅加载包含至少一个包含子字符串'aol.com'
的email
字段的Address
对象的User
对象;User.addresses
集合将仅包含这些Address
条目,而不包括实际与该集合关联的任何其他Address
条目。
提示
在所有情况下,除非有明确的指示要这样做,否则 SQLAlchemy ORM 不会覆盖已加载的属性和集合。由于正在使用标识映射,通常情况下,ORM 查询返回的对象实际上已经存在并加载到内存中。因此,当使用contains_eager()
以另一种方式填充集合时,通常最好像上面所示那样使用填充现有,以便已加载的集合使用新数据进行刷新。populate_existing
选项将重置已存在的所有属性,包括挂起的更改,因此在使用之前请确保刷新所有数据。使用具有其默认行为的Session
的 autoflush 足以。
注意
使用contains_eager()
加载的定制集合不是“粘性”的;也就是说,下次加载该集合时,它将以其通常的默认内容加载。如果对象过期,则集合可能会重新加载,这在使用默认会话设置时每当使用 Session.commit()
、Session.rollback()
方法时,或者使用 Session.expire_all()
或 Session.expire()
方法时会发生。
另请参阅
向加载器选项添加条件 - 现代 API 允许在任何关系加载器选项中直接添加 WHERE 条件
使用 contains_eager() 加载定制过滤的集合结果
当我们使用contains_eager()
时,我们正在构建用于填充集合的 SQL。由此自然而然地,我们可以选择修改集合的预期存储值,通过编写我们的 SQL 以加载集合或标量属性的子集元素。
提示
SQLAlchemy 现在有一种更简单的方法来做到这一点,即允许将 WHERE 条件直接添加到加载器选项,例如joinedload()
和selectinload()
,使用PropComparator.and_()
。有关示例,请参见向加载器选项添加条件部分。
如果要使用比简单的 WHERE 子句更复杂的 SQL 条件或修改器查询相关集合,则这里描述的技术仍然适用。
例如,我们可以加载一个User
对象,并且仅通过过滤联接数据并使用contains_eager()
将其路由到.addresses
集合,从而急切地加载特定地址,还使用 Populate Existing 确保任何已加载的集合都被覆盖:
stmt = ( select(User) .join(User.addresses) .filter(Address.email_address.like("%@aol.com")) .options(contains_eager(User.addresses)) .execution_options(populate_existing=True) )
上面的查询将仅加载包含其email
字段中包含子字符串'aol.com'
的Address
对象的User
对象;User.addresses
集合将仅包含这些Address
条目,而不是与集合实际相关联的任何其他Address
条目。
提示
在所有情况下,SQLAlchemy ORM 不会覆盖已加载的属性和集合,除非被告知要这样做。由于正在使用身份映射,通常情况下,ORM 查询返回的对象实际上已经存在并且在内存中已加载。因此,当使用contains_eager()
以替代方式填充集合时,通常最好使用上面示例中所示的 Populate Existing,以便已加载的集合可以用新数据刷新。populate_existing
选项将重置已经存在的所有属性,包括待处理的更改,因此请确保在使用之前刷新所有数据。使用具有其默认行为的Session
的 autoflush 足以。
注意
我们使用contains_eager()
加载的定制集合不是“粘性”的;也就是说,下次加载此集合时,它将以其通常的默认内容加载。 如果对象过期,则可能重新加载集合,这会在使用默认会话设置时每当使用Session.commit()
、Session.rollback()
方法,或者使用Session.expire_all()
或Session.expire()
方法时发生。
另请参阅
向加载器选项添加条件 - 现代 API 允许在任何关系加载器选项中直接添加 WHERE 条件
关系加载器 API
对象名称 | 描述 |
contains_eager(*keys, **kw) | 表示应从查询中手动指定的列急切加载给定属性。 |
defaultload(*keys) | 表示应使用预定义的加载器样式加载属性。 |
immediateload(*keys, [recursion_depth]) | 表示应使用带有每个属性 SELECT 语句的立即加载来加载给定属性。 |
joinedload(*keys, **kw) | 表示应使用连接的急切加载来加载给定属性。 |
lazyload(*keys) | 表示应使用“懒惰”加载来加载给定属性。 |
Load | 代表修改 ORM 启用的Select 或传统Query 状态以影响加载各种映射属性的加载器选项。 |
noload(*keys) | 表示给定关系属性应保持未加载状态。 |
raiseload(*keys, **kw) | 表示给定属性在访问时应引发错误。 |
selectinload(*keys, [recursion_depth]) | 表示应使用 SELECT IN 急切加载来加载给定属性。 |
subqueryload(*keys) | 表示应使用子查询急切加载来加载给定属性。 |
function sqlalchemy.orm.contains_eager(*keys: Literal['*'] | QueryableAttribute[Any], **kw: Any) → _AbstractLoad
表示应从查询中手动指定的列急���加载给定属性。
此函数是Load
接口的一部分,支持方法链接和独立操作。
此选项与加载所需行的显式连接一起使用,即:
sess.query(Order).join(Order.user).options( contains_eager(Order.user) )
上述查询将从 Order
实体连接到其相关的 User
实体,并且返回的 Order
对象将预先填充 Order.user
属性。
还可以用于自定义急切加载集合中的条目;查询通常会使用 填充现有 执行选项,假设父对象的主要集合可能已经加载:
sess.query(User).join(User.addresses).filter( Address.email_address.like("%@aol.com") ).options(contains_eager(User.addresses)).populate_existing()
有关完整的使用详细信息,请参阅 将显式连接/语句路由到急切加载的集合中 部分。
另请参见
关系加载技术
将显式连接/语句路由到急切加载的集合中
function sqlalchemy.orm.defaultload(*keys: Literal['*'] | QueryableAttribute[Any]) → _AbstractLoad
指示属性应使用其预定义的加载器样式加载。
此加载选项的行为是不更改属性的当前加载样式,这意味着将使用先前配置的样式,或者如果没有选择先前的样式,则将使用默认加载。
此方法用于将其他加载器选项链接到属性链中的进一步位置,而不更改链中的链接的加载器样式。例如,要为元素的元素设置连接的急切加载:
session.query(MyClass).options( defaultload(MyClass.someattribute).joinedload( MyOtherClass.someotherattribute ) )
defaultload()
也可用于在相关类上设置列级选项,即 defer()
和 undefer()
:
session.scalars( select(MyClass).options( defaultload(MyClass.someattribute) .defer("some_column") .undefer("some_other_column") ) )
另请参见
使用 Load.options() 指定子选项
Load.options()
function sqlalchemy.orm.immediateload(*keys: Literal['*'] | QueryableAttribute[Any], recursion_depth: int | None = None) → _AbstractLoad
指示应使用立即加载和每个属性的 SELECT 语句加载给定属性。
加载是使用“懒加载器”策略实现的,不会触发任何额外的急切加载器。
immediateload()
选项通常被 selectinload()
选项替代,后者通过为所有加载的对象发出 SELECT 语句来更有效地执行相同的任务。
此函数是 Load
接口的一部分,并支持方法链接和独立操作。
参数:
recursion_depth – 递归深度
可选整数;当与自引用关系一起设置为正整数时,表示“selectin”加载将自动继续这么多级别,直到找不到任何项目为止。
注意
immediateload.recursion_depth
选项目前仅支持自引用关系。目前还没有选项可以自动遍历涉及多个关系的递归结构。
警告
此参数是新的实验性参数,应该视为“alpha”状态
2.0 版本中新增:添加immediateload.recursion_depth
另请参见
关系加载技术
Select IN 加载
function sqlalchemy.orm.joinedload(*keys: Literal['*'] | QueryableAttribute[Any], **kw: Any) → _AbstractLoad
表示应该使用连接的快速加载来加载给定的属性。
此函数是Load
接口的一部分,支持方法链和独立操作。
示例:
# joined-load the "orders" collection on "User" select(User).options(joinedload(User.orders)) # joined-load Order.items and then Item.keywords select(Order).options( joinedload(Order.items).joinedload(Item.keywords) ) # lazily load Order.items, but when Items are loaded, # joined-load the keywords collection select(Order).options( lazyload(Order.items).joinedload(Item.keywords) )
参数:
innerjoin –
如果True
,表示连接的急切加载应该使用内部连接而不是左外连接的默认值:
select(Order).options(joinedload(Order.user, innerjoin=True))
为了链接多个急切加载在一起,其中一些可能是 OUTER,另一些是 INNER,右嵌套连接用于链接它们:
select(A).options( joinedload(A.bs, innerjoin=False).joinedload( B.cs, innerjoin=True ) )
上述查询通过“outer” join 连接 A.bs 和通过“inner” join 连接 B.cs,将连接呈现为“a LEFT OUTER JOIN (b JOIN c)”。
innerjoin
标志也可以用术语"unnested"
来表示。这表示应该使用 INNER JOIN,除非连接到左侧的 LEFT OUTER JOIN,这种情况下它将呈现为 LEFT OUTER JOIN。例如,假设A.bs
是一个 outerjoin:
select(A).options( joinedload(A.bs).joinedload(B.cs, innerjoin="unnested") )
上述连接将呈现为“a LEFT OUTER JOIN b LEFT OUTER JOIN c”,而不是“a LEFT OUTER JOIN (b JOIN c)”。
注意
“unnested”标志不会影响从多对多关联表(例如配置为relationship.secondary
的表)到目标表的 JOIN 渲染;为了结果的正确性,这些连接始终是 INNER 的,因此如果连接到 OUTER join,它们将是右嵌套的。
注意
joinedload()
生成的连接是匿名别名。连接进行的条件无法修改,ORM 启用的Select
或传统的Query
也不能以任何方式引用这些连接,包括排序。有关详细信息,请参见急切加载之道。
要生成一个明确可用的特定 SQL JOIN,请使用Select.join()
和Query.join()
。要将显式的 JOIN 与集合的急加载结合起来,请使用contains_eager()
;参见将显式 JOIN/语句路由到急加载的集合。
另请参阅
关系加载技术
连接急加载
function sqlalchemy.orm.lazyload(*keys: Literal['*'] | QueryableAttribute[Any]) → _AbstractLoad
表示应该使用“懒加载”来加载给定的属性。
此函数是Load
接口的一部分,支持方法链和独立操作。
另请参阅
关系加载技术
懒加载
class sqlalchemy.orm.Load
表示加载器选项,用于修改 ORM 启用的Select
或传统Query
的状态,以影响加载各种映射属性的方式。
在大多数情况下,当使用查询选项像joinedload()
、defer()
或类似的选项时,Load
对象通常会在幕后隐式使用。除了一些非常特殊的情况外,通常不会直接实例化它。
另请参阅
每个实体的通配符加载策略 - 演示了直接使用Load
可能有用的示例
成员
contains_eager(), defaultload(), defer(), get_children(), immediateload(), inherit_cache, joinedload(), lazyload(), load_only(), noload(), options(), process_compile_state(), process_compile_state_replaced_entities(), propagate_to_loaders, raiseload(), selectin_polymorphic(), selectinload(), subqueryload(), undefer(), undefer_group(), with_expression()
类签名
类sqlalchemy.orm.Load
(sqlalchemy.orm.strategy_options._AbstractLoad
)
method contains_eager(attr: _AttrType, alias: _FromClauseArgument | None = None, _is_chain: bool = False) → Self
从 sqlalchemy.orm.strategy_options._AbstractLoad.contains_eager
方法继承 sqlalchemy.orm.strategy_options._AbstractLoad
生成一个新的带有contains_eager()
选项的Load
对象。
查看contains_eager()
的使用示例。
method defaultload(attr: Literal['*'] | QueryableAttribute[Any]) → Self
从 sqlalchemy.orm.strategy_options._AbstractLoad.defaultload
方法继承 sqlalchemy.orm.strategy_options._AbstractLoad
生成一个新的带有defaultload()
选项的Load
对象。
查看defaultload()
的使用示例。
method defer(key: Literal['*'] | QueryableAttribute[Any], raiseload: bool = False) → Self
从 sqlalchemy.orm.strategy_options._AbstractLoad.defer
方法继承 sqlalchemy.orm.strategy_options._AbstractLoad
生成一个新的带有defer()
选项的Load
对象。
查看defer()
的使用示例。
method get_children(*, omit_attrs: Tuple[str, ...] = (), **kw: Any) → Iterable[HasTraverseInternals]
从 HasTraverseInternals.get_children()
方法继承 HasTraverseInternals
返回此HasTraverseInternals
的即时子项HasTraverseInternals
。
用于访问遍历。
**kw 可能包含更改返回集合的标志,例如返回子项的子集以减少较大的遍历,或者从不同上下文返回子项(例如模式级集合而不是从子句级返回的)。
method immediateload(attr: Literal['*'] | QueryableAttribute[Any], recursion_depth: int | None = None) → Self
从 sqlalchemy.orm.strategy_options._AbstractLoad.immediateload
方法继承 sqlalchemy.orm.strategy_options._AbstractLoad
生成一个新的带有immediateload()
选项的Load
对象。
查看immediateload()
的使用示例。
attribute inherit_cache: bool | None = None
从 HasCacheKey
的 HasCacheKey.inherit_cache
属性继承
指示此HasCacheKey
实例是否应使用其直接超类使用的缓存键生成方案。
该属性默认为None
,表示构造尚未考虑是否适合参与缓存;这在功能上等效于将值设置为False
,但还会发出警告。
如果对象对应的 SQL 不基于本类的属性而是本类的父类属性,则可以将此标志设置为True
。
另请参阅
为自定义构造启用缓存支持 - 有关为第三方或用户定义的 SQL 构造设置HasCacheKey.inherit_cache
属性的一般指南。
method joinedload(attr: Literal['*'] | QueryableAttribute[Any], innerjoin: bool | None = None) → Self
继承自 sqlalchemy.orm.strategy_options._AbstractLoad.joinedload
方法的 sqlalchemy.orm.strategy_options._AbstractLoad
使用joinedload()
选项生成一个新的Load
对象。
请参阅joinedload()
以查看用法示例。
method lazyload(attr: Literal['*'] | QueryableAttribute[Any]) → Self
继承自 sqlalchemy.orm.strategy_options._AbstractLoad.lazyload
方法的 sqlalchemy.orm.strategy_options._AbstractLoad
使用lazyload()
选项生成一个新的Load
对象。
请参阅lazyload()
以查看用法示例。
method load_only(*attrs: Literal['*'] | QueryableAttribute[Any], raiseload: bool = False) → Self
继承自 sqlalchemy.orm.strategy_options._AbstractLoad.load_only
方法的 sqlalchemy.orm.strategy_options._AbstractLoad
使用load_only()
选项生成一个新的Load
对象。
请参阅load_only()
以查看用法示例。
method noload(attr: Literal['*'] | QueryableAttribute[Any]) → Self
继承自 sqlalchemy.orm.strategy_options._AbstractLoad.noload
方法的 sqlalchemy.orm.strategy_options._AbstractLoad
使用noload()
选项生成一个新的Load
对象。
请参阅noload()
以查看用法示例。
method options(*opts: _AbstractLoad) → Self
将一系列选项作为此Load
对象的子选项应用。
例如:
query = session.query(Author) query = query.options( joinedload(Author.book).options( load_only(Book.summary, Book.excerpt), joinedload(Book.citations).options( joinedload(Citation.author) ) ) )
参数:
*opts – 应应用于此Load
对象指定路径的一系列加载器选项对象(最终为Load
对象)。
新版本 1.3.6 中新增。
另请参阅
defaultload()
使用 Load.options() 指定子选项
method process_compile_state(compile_state: ORMCompileState) → None
继承自 sqlalchemy.orm.strategy_options._AbstractLoad.process_compile_state
方法的 sqlalchemy.orm.strategy_options._AbstractLoad
对给定的ORMCompileState
应用修改。
此方法是特定CompileStateOption
的实现的一部分,仅在编译 ORM 查询时内部调用。
method process_compile_state_replaced_entities(compile_state: ORMCompileState, mapper_entities: Sequence[_MapperEntity]) → None
继承自 sqlalchemy.orm.strategy_options._AbstractLoad.process_compile_state_replaced_entities
方法的 sqlalchemy.orm.strategy_options._AbstractLoad
对给定的ORMCompileState
应用修改,给出仅由with_only_columns()
或with_entities()
替换的实体。
此方法是特定CompileStateOption
的实现的一部分,仅在编译 ORM 查询时内部调用。
1.4.19 版本中的新功能。
attribute propagate_to_loaders: bool
继承自 sqlalchemy.orm.strategy_options._AbstractLoad.propagate_to_loaders
属性的 sqlalchemy.orm.strategy_options._AbstractLoad
如果为 True,则表示此选项应该传递到关系懒加载器的“次要”SELECT 语句,以及属性加载/刷新操作。
method raiseload(attr: Literal['*'] | QueryableAttribute[Any], sql_only: bool = False) → Self
继承自 sqlalchemy.orm.strategy_options._AbstractLoad.raiseload
方法的 sqlalchemy.orm.strategy_options._AbstractLoad
使用raiseload()
选项生成一个新的Load
对象。
查看raiseload()
以查看用法示例。
method selectin_polymorphic(classes: Iterable[Type[Any]]) → Self
继承自 sqlalchemy.orm.strategy_options._AbstractLoad.selectin_polymorphic
方法的 sqlalchemy.orm.strategy_options._AbstractLoad
使用selectin_polymorphic()
选项生成一个新的Load
对象。
查看selectin_polymorphic()
以查看用法示例。
method selectinload(attr: Literal['*'] | QueryableAttribute[Any], recursion_depth: int | None = None) → Self
继承自 sqlalchemy.orm.strategy_options._AbstractLoad.selectinload
方法的 sqlalchemy.orm.strategy_options._AbstractLoad
使用selectinload()
选项生成一个新的Load
对象。
查看selectinload()
以查看用法示例。
method subqueryload(attr: Literal['*'] | QueryableAttribute[Any]) → Self
继承自 sqlalchemy.orm.strategy_options._AbstractLoad.subqueryload
方法的 sqlalchemy.orm.strategy_options._AbstractLoad
使用subqueryload()
选项生成一个新的Load
对象。
查看subqueryload()
以查看用法示例。
method undefer(key: Literal['*'] | QueryableAttribute[Any]) → Self
继承自 sqlalchemy.orm.strategy_options._AbstractLoad.undefer
方法的 sqlalchemy.orm.strategy_options._AbstractLoad
使用undefer()
选项生成一个新的Load
对象。
请参见undefer()
获取用法示例。
method undefer_group(name: str) → Self
继承自 sqlalchemy.orm.strategy_options._AbstractLoad.undefer_group
方法的 sqlalchemy.orm.strategy_options._AbstractLoad
使用undefer_group()
选项生成新的Load
对象。
请参见undefer_group()
获取用法示例。
method with_expression(key: _AttrType, expression: _ColumnExpressionArgument[Any]) → Self
继承自 sqlalchemy.orm.strategy_options._AbstractLoad.with_expression
方法的 sqlalchemy.orm.strategy_options._AbstractLoad
使用with_expression()
选项生成新的Load
对象。
请参见with_expression()
获取用法示例。
function sqlalchemy.orm.noload(*keys: Literal['*'] | QueryableAttribute[Any]) → _AbstractLoad
表示给定的关系属性应保持未加载状态。
当访问关系属性时,关系属性将返回None
,而不产生任何加载效果。
此功能是Load
接口的一部分,支持方法链和独立操作。
noload()
仅适用于relationship()
属性。
注意
使用relationship.lazy
参数将此加载策略设置为关系的默认策略可能会导致刷新时出现问题,例如,如果删除操作需要加载相关对象,而返回的是None
。
参见
关系加载技术
function sqlalchemy.orm.raiseload(*keys: Literal['*'] | QueryableAttribute[Any], **kw: Any) → _AbstractLoad
表示如果访问给定的属性,应该引发错误。
使用raiseload()
配置的关系属性在访问时将引发InvalidRequestError
。这种方式通常很有用,当应用程序试图确保在特定上下文中访问的所有关系属性都已通过急加载加载时。这种策略将导致立即引发异常,而不必查看 SQL 日志以确保不会发生延迟加载。
raiseload()
仅适用于 relationship()
属性。为了将在基于列的属性上应用 SQL 异常处理行为,应在 defer()
加载器选项的 defer.raiseload
参数上使用。
参数:
sql_only – 如果为 True,则仅在延迟加载会发出 SQL 时引发异常,但如果仅检查标识映射或确定相关值由于缺少键应为 None,则不会引发异常。当为 False 时,该策略将引发所有类型的关系加载异常。
此函数是 Load
接口的一部分,支持方法链式和独立操作。
另请参阅
关系加载技术
使用 raiseload 防止不需要的延迟加载
使用 raiseload 防止延迟加载列
function sqlalchemy.orm.selectinload(*keys: Literal['*'] | QueryableAttribute[Any], recursion_depth: int | None = None) → _AbstractLoad
指示应使用 SELECT IN 即时加载来加载给定的属性。
此函数是 Load
接口的一部分,支持方法链式和独立操作。
示例:
# selectin-load the "orders" collection on "User" select(User).options(selectinload(User.orders)) # selectin-load Order.items and then Item.keywords select(Order).options( selectinload(Order.items).selectinload(Item.keywords) ) # lazily load Order.items, but when Items are loaded, # selectin-load the keywords collection select(Order).options( lazyload(Order.items).selectinload(Item.keywords) )
参数:
递归深度 –
可选整数;当与自引用关系一起设置为正整数时,表示“选择加载”将自动深入到指定的层级直到找不到任何项目。
注意
selectinload.recursion_depth
选项目前仅支持自引用关系。目前还没有自动遍历多个关系的递归结构的选项。
此外,selectinload.recursion_depth
参数是新的实验性参数,并且应被视为 2.0 系列的“alpha”状态。
2.0 版本中新增:添加 selectinload.recursion_depth
另请参阅
关系加载技术
选择 IN 加载
function sqlalchemy.orm.subqueryload(*keys: Literal['*'] | QueryableAttribute[Any]) → _AbstractLoad
指示应使用子查询即时加载来加载给定的属性。
此函数是 Load
接口的一部分,支持方法链式和独立操作。
示例:
# subquery-load the "orders" collection on "User" select(User).options(subqueryload(User.orders)) # subquery-load Order.items and then Item.keywords select(Order).options( subqueryload(Order.items).subqueryload(Item.keywords) ) # lazily load Order.items, but when Items are loaded, # subquery-load the keywords collection select(Order).options( lazyload(Order.items).subqueryload(Item.keywords) )
另请参阅
关系加载技术
子查询即时加载