列加载选项¶
关于本文档
本节介绍有关列加载的其他选项。使用的映射包括存储大字符串值的列,我们可能希望在加载它们时对其进行限制。
查看此页面的 ORM 设置。下面的一些示例将重新定义 Book
映射器以修改某些列定义。
使用 Column Deferral 限制哪些列加载¶
列延迟是指在查询该类型的对象时从 SELECT 语句中省略的 ORM 映射列。这里的一般基本原理是性能,如果 table 很少使用具有可能较大的数据值的列,因为在每个查询中完全加载这些列可能会占用大量时间和/或内存。SQLAlchemy ORM 提供了多种方法来控制加载实体时列的加载。
本节中的大多数示例都说明了 ORM 加载器选项。这些是传递给 Select
对象的 Select.options()
方法的小结构,然后在将对象编译为 SQL 字符串时由 ORM 使用。
使用 load_only()
减少加载的列¶
load_only()
loader 选项是加载已知仅访问一小部分列的对象时使用的最方便选项。此选项接受可变数量的类绑定属性对象,这些对象指示应加载的列映射属性,其中主键之外的所有其他列映射属性将不是 columns fetched 的一部分。在下面的示例中,Book
类包含列 .title
、.summary
和 .cover_photo
。用
load_only()
我们可以指示 ORM 只加载
.title
和 .summary
列:
>>> from sqlalchemy import select
>>> from sqlalchemy.orm import load_only
>>> stmt = select(Book).options(load_only(Book.title, Book.summary))
>>> books = session.scalars(stmt).all()
SELECT book.id, book.title, book.summary
FROM book
[...] ()
>>> for book in books:
... print(f"{book.title} {book.summary}")
100 Years of Krabby Patties some long summary
Sea Catch 22 another long summary
The Sea Grapes of Wrath yet another summary
A Nut Like No Other some long summary
Geodesic Domes: A Retrospective another long summary
Rocketry for Squirrels yet another summary
在上面,SELECT 语句省略了 .cover_photo
列,只包括 .title
和 .summary
以及主键列
.id
的 ID 文件;ORM 通常总是获取主键列,因为这些列是建立行的身份所必需的。
加载后,对象通常会将延迟加载行为应用于剩余的未加载属性,这意味着当首次访问任何属性时,将在当前事务中发出 SQL 语句以加载该值。下面,访问 .cover_photo
会发出 SELECT 语句来加载其值:
>>> img_data = books[0].cover_photo
SELECT book.cover_photo AS book_cover_photo
FROM book
WHERE book.id = ?
[...] (1,)
延迟加载始终使用对象处于持久状态的 Session
发出。如果对象已分离
在任何 Session
中,作都会失败,并引发异常。
作为访问时延迟加载的替代方法,延迟列也可以配置为在访问时引发信息异常,而不管其附件状态如何。使用 load_only()
构造时,可以使用 load_only.raiseload
参数来指示这一点。有关背景和示例,请参阅使用 raiseload 防止延迟列加载部分。
提示
如其他地方所述,使用
异步 I/O (asyncio)。
对多个实体使用 load_only()
¶
load_only()
将自身限制为引用的单个实体
towards 在其属性列表中(传递一个跨度更高的
而不是单个实体)。在下面的示例中,给定的
load_only()
选项仅适用于 Book
实体。用户
同时被选中的实体不受影响;在生成的 SELECT
语句,则 user_account
的所有列都存在,而只有
book.id
和 book.title
存在于 book
表中:
>>> stmt = select(User, Book).join_from(User, Book).options(load_only(Book.title))
>>> print(stmt)
SELECT user_account.id, user_account.name, user_account.fullname,
book.id AS id_1, book.title
FROM user_account JOIN book ON user_account.id = book.owner_id
如果我们想将 load_only()
选项同时应用于 User
和
Book
,我们将使用两个单独的选项:
>>> stmt = (
... select(User, Book)
... .join_from(User, Book)
... .options(load_only(User.name), load_only(Book.title))
... )
>>> print(stmt)
SELECT user_account.id, user_account.name, book.id AS id_1, book.title
FROM user_account JOIN book ON user_account.id = book.owner_id
使用 defer()
省略特定列¶
defer()
加载器选项是
load_only()
的 API 中,它允许将单个特定列标记为 “don't load”。在下面的示例中,defer()
直接应用于
.cover_photo
列,保持所有其他列的行为不变:
>>> from sqlalchemy.orm import defer
>>> stmt = select(Book).where(Book.owner_id == 2).options(defer(Book.cover_photo))
>>> books = session.scalars(stmt).all()
SELECT book.id, book.owner_id, book.title, book.summary
FROM book
WHERE book.owner_id = ?
[...] (2,)
>>> for book in books:
... print(f"{book.title}: {book.summary}")
A Nut Like No Other: some long summary
Geodesic Domes: A Retrospective: another long summary
Rocketry for Squirrels: yet another summary
与 load_only()
的情况一样,默认情况下,卸载的列在使用延迟加载访问时将加载自身:
>>> img_data = books[0].cover_photo
SELECT book.cover_photo AS book_cover_photo
FROM book
WHERE book.id = ?
[...] (4,)
可以在一个语句中使用多个 defer()
选项,以便将多个列标记为 deferred。
与 load_only()
的情况一样,defer()
选项
还包括让 Deferred 属性在
access 而不是延迟加载。 这在
使用 raiseload 来防止延迟的柱载荷。
使用 raiseload 来防止延迟的列加载¶
当使用 load_only()
或 defer()
加载器选项时,在对象上标记为 deferred 的属性具有默认行为,即首次访问时,将在当前事务中发出 SELECT 语句以加载其值。通常需要防止此负载发生,而是在访问该属性时引发异常,这表明不需要在数据库中查询此列。一个典型的场景是,对象加载了作继续所需的所有已知列,然后将这些列传递到视图层。应该捕获在视图层中发出的任何其他 SQL作,以便可以调整预先加载作以适应预先添加的数据,而不是产生额外的延迟加载。
对于此用例,defer()
和 load_only()
选项包括一个布尔参数 defer.raiseload
,当设置为
True
将导致受影响的属性在访问时引发。在下面的示例中,延迟列 .cover_photo
将禁止属性访问:
>>> book = session.scalar(
... select(Book).options(defer(Book.cover_photo, raiseload=True)).where(Book.id == 4)
... )
SELECT book.id, book.owner_id, book.title, book.summary
FROM book
WHERE book.id = ?
[...] (4,)
>>> book.cover_photo
Traceback (most recent call last):
...
sqlalchemy.exc.InvalidRequestError: 'Book.cover_photo' is not available due to raiseload=True
当使用 load_only()
命名一组特定的非延迟列时,可以使用 load_only.raiseload
参数将 raiseload
行为应用于其余列,该参数将应用于所有延迟属性:
>>> session.expunge_all()
>>> book = session.scalar(
... select(Book).options(load_only(Book.title, raiseload=True)).where(Book.id == 5)
... )
SELECT book.id, book.title
FROM book
WHERE book.id = ?
[...] (5,)
>>> book.summary
Traceback (most recent call last):
...
sqlalchemy.exc.InvalidRequestError: 'Book.summary' is not available due to raiseload=True
注意
目前还不能混合使用 load_only()
和 defer()
选项,这些选项按顺序在一个语句中一起引用同一实体
更改某些属性的 raiseLoad
行为;目前,这样做会产生 Attribute 的 undefined 加载行为。
另请参阅
defer.raiseload
功能是列级版本
与可用于关系的相同 “raiseload” 功能。
有关关系的 “raiseload”,请参阅
在
Relationship Loading Techniques 部分。
在 Mapping 上配置 Column Deferral¶
defer()
的功能可用作
映射列,这可能适用于不应加载的列
无条件地对每个查询。要进行配置,请使用
mapped_column.deferred
参数
mapped_column()
中。下面的示例说明了
Book
将默认列延迟应用于摘要
,以及
cover_photo
列:
>>> class Book(Base):
... __tablename__ = "book"
... id: Mapped[int] = mapped_column(primary_key=True)
... owner_id: Mapped[int] = mapped_column(ForeignKey("user_account.id"))
... title: Mapped[str]
... summary: Mapped[str] = mapped_column(Text, deferred=True)
... cover_photo: Mapped[bytes] = mapped_column(LargeBinary, deferred=True)
...
... def __repr__(self) -> str:
... return f"Book(id={self.id!r}, title={self.title!r})"
使用上述映射,针对 Book
的查询将自动不包含 summary
和 cover_photo
列:
>>> book = session.scalar(select(Book).where(Book.id == 2))
SELECT book.id, book.owner_id, book.title
FROM book
WHERE book.id = ?
[...] (2,)
与所有 deferral 的情况一样,首次访问加载对象上的 defered 属性时的默认行为是它们将延迟加载
它们的价值:
>>> img_data = book.cover_photo
SELECT book.cover_photo AS book_cover_photo
FROM book
WHERE book.id = ?
[...] (2,)
与 defer()
和 load_only()
一样
loader 选项中,Mapper 级别延迟还包括一个用于 raiseLoad
的选项
行为,而不是延迟加载,当没有其他选项时
出现在声明中。 这允许映射
默认情况下不会加载,并且永远不会在没有 explicit 的情况下延迟加载
语句中使用的指令。 请参阅该部分
配置 mapper 级别的 “raiseload” 行为,了解如何配置和使用此行为的背景信息。
使用 deferred()
进行命令式映射器,映射 SQL 表达式¶
deferred()
函数是更早、更通用的函数
“deferred column” 映射指令,该指令在引入
mapped_column()
结构。
deferred()
在配置 ORM 映射器时使用,并接受
arbitrary SQL 表达式或
Column
对象。因此,它适合与非声明性命令式映射一起使用,将其传递给 map_imperatively.properties
字典:
from sqlalchemy import Blob
from sqlalchemy import Column
from sqlalchemy import ForeignKey
from sqlalchemy import Integer
from sqlalchemy import String
from sqlalchemy import Table
from sqlalchemy import Text
from sqlalchemy.orm import registry
mapper_registry = registry()
book_table = Table(
"book",
mapper_registry.metadata,
Column("id", Integer, primary_key=True),
Column("title", String(50)),
Column("summary", Text),
Column("cover_image", Blob),
)
class Book:
pass
mapper_registry.map_imperatively(
Book,
book_table,
properties={
"summary": deferred(book_table.c.summary),
"cover_image": deferred(book_table.c.cover_image),
},
)
deferred()
也可以用来代替 column_property()
何时应延迟加载映射的 SQL 表达式:
from sqlalchemy.orm import deferred
class User(Base):
__tablename__ = "user"
id: Mapped[int] = mapped_column(primary_key=True)
firstname: Mapped[str] = mapped_column()
lastname: Mapped[str] = mapped_column()
fullname: Mapped[str] = deferred(firstname + " " + lastname)
使用 undefer()
来 “急切” 加载延迟列¶
默认情况下,在映射上将列配置为 defer 后,
undefer()
选项将导致任何通常被延迟的列都是 undeferred,也就是说,预先加载映射的所有其他列。例如,我们可以将 undefer()
应用于
Book.summary
列,该列在上一个映射中指示为 deferred:
>>> from sqlalchemy.orm import undefer
>>> book = session.scalar(select(Book).where(Book.id == 2).options(undefer(Book.summary)))
SELECT book.id, book.owner_id, book.title, book.summary
FROM book
WHERE book.id = ?
[...] (2,)
Book.summary
列现在已预先加载,无需发出其他 SQL 即可访问:
>>> print(book.summary)
another long summary
以组的形式加载延迟列¶
通常,当列使用 mapped_column (deferred=True)
映射时,当
deferred 属性,将发出 SQL 以加载
仅该特定列,没有其他列,即使映射具有其他列
也被标记为 Deferred。在通常情况下,延迟的
attribute 是一组属性的一部分,这些属性应该一次加载,而不是
比为每个属性单独发出 SQL 时,
mapped_column.deferred_group
参数,该参数接受任意字符串,该字符串将定义一组要未延迟的公共列:
>>> class Book(Base):
... __tablename__ = "book"
... id: Mapped[int] = mapped_column(primary_key=True)
... owner_id: Mapped[int] = mapped_column(ForeignKey("user_account.id"))
... title: Mapped[str]
... summary: Mapped[str] = mapped_column(
... Text, deferred=True, deferred_group="book_attrs"
... )
... cover_photo: Mapped[bytes] = mapped_column(
... LargeBinary, deferred=True, deferred_group="book_attrs"
... )
...
... def __repr__(self) -> str:
... return f"Book(id={self.id!r}, title={self.title!r})"
使用上述映射,访问 summary
或 cover_photo
将仅使用一个 SELECT 语句一次加载两列:
>>> book = session.scalar(select(Book).where(Book.id == 2))
SELECT book.id, book.owner_id, book.title
FROM book
WHERE book.id = ?
[...] (2,)
>>> img_data, summary = book.cover_photo, book.summary
SELECT book.summary AS book_summary, book.cover_photo AS book_cover_photo
FROM book
WHERE book.id = ?
[...] (2,)
使用 undefer_group()
按组取消延迟¶
如果 deferred 列配置了 mapped_column.deferred_group
如上一节所述,
可以使用 undefer_group()
指示整个组预先加载
选项,传递要预先加载的组的字符串名称:
>>> from sqlalchemy.orm import undefer_group
>>> book = session.scalar(
... select(Book).where(Book.id == 2).options(undefer_group("book_attrs"))
... )
SELECT book.id, book.owner_id, book.title, book.summary, book.cover_photo
FROM book
WHERE book.id = ?
[...] (2,)
摘要
和cover_photo
均可用,无需额外加载:
>>> img_data, summary = book.cover_photo, book.summary
取消延迟通配符¶
大多数 ORM 加载器选项都接受通配符表达式,由
“*”
,这表示该选项应应用于所有相关属性。如果映射具有一系列延迟列,则可以通过指示通配符来立即取消延迟,而无需使用组名称:
>>> book = session.scalar(select(Book).where(Book.id == 3).options(undefer("*")))
SELECT book.id, book.owner_id, book.title, book.summary, book.cover_photo
FROM book
WHERE book.id = ?
[...] (3,)
配置 mapper 级别的 “raiseload” 行为¶
在 Using raiseload to prevent deferred column loads 中首次引入的 “raiseload” 行为可能会
也作为默认映射器级别行为应用,使用
mapped_column.deferred_raiseload
参数
mapped_column()
中。 使用此参数时,受影响的列
将在所有情况下在访问时引发,除非使用
undefer()
或 load_only()
在查询时:
>>> class Book(Base):
... __tablename__ = "book"
... id: Mapped[int] = mapped_column(primary_key=True)
... owner_id: Mapped[int] = mapped_column(ForeignKey("user_account.id"))
... title: Mapped[str]
... summary: Mapped[str] = mapped_column(Text, deferred=True, deferred_raiseload=True)
... cover_photo: Mapped[bytes] = mapped_column(
... LargeBinary, deferred=True, deferred_raiseload=True
... )
...
... def __repr__(self) -> str:
... return f"Book(id={self.id!r}, title={self.title!r})"
使用上述映射,默认情况下,.summary
和 .cover_photo
列是不可加载的:
>>> book = session.scalar(select(Book).where(Book.id == 2))
SELECT book.id, book.owner_id, book.title
FROM book
WHERE book.id = ?
[...] (2,)
>>> book.summary
Traceback (most recent call last):
...
sqlalchemy.exc.InvalidRequestError: 'Book.summary' is not available due to raiseload=True
只有在查询时覆盖它们的行为,通常使用
undefer()
或 undefer_group()
或不太常见的
defer()
来加载 attribute。 以下示例适用
undefer('*')
取消延迟所有属性,同时使用
Populate Existing 以刷新已加载对象的加载器选项:
>>> book = session.scalar(
... select(Book)
... .where(Book.id == 2)
... .options(undefer("*"))
... .execution_options(populate_existing=True)
... )
SELECT book.id, book.owner_id, book.title, book.summary, book.cover_photo
FROM book
WHERE book.id = ?
[...] (2,)
>>> book.summary
'another long summary'
将任意 SQL 表达式加载到对象上¶
如选择 ORM 实体和属性等内容所述,select()
结构可用于加载任意 SQL 表达式
在结果集中。 例如,如果我们想要发出一个加载
User
对象,但也包括每个用户
拥有的书籍数量的计数,我们可以使用 func.count(Book.id)
向查询添加一个 “count” 列,其中包括 JOIN to Book
以及 GROUP BY 所有者 ID。这将产生 Row
对象,每个对象都包含两个条目,一个用于 User
,一个用于 func.count(Book.id):
>>> from sqlalchemy import func
>>> stmt = select(User, func.count(Book.id)).join_from(User, Book).group_by(Book.owner_id)
>>> for user, book_count in session.execute(stmt):
... print(f"Username: {user.name} Number of books: {book_count}")
SELECT user_account.id, user_account.name, user_account.fullname,
count(book.id) AS count_1
FROM user_account JOIN book ON user_account.id = book.owner_id
GROUP BY book.owner_id
[...] ()
Username: spongebob Number of books: 3
Username: sandy Number of books: 3
在上面的示例中,User 实体和
“book count” SQL 表达式分别返回。但是,一个常见的用例是生成一个查询,该查询将单独产生 User
对象,例如,可以使用
Session.scalars()
中,其中 func.count(Book.id)
SQL 表达式动态应用于每个 User
实体。最终结果类似于使用 column_property()
将任意 SQL 表达式映射到类的情况,不同之处在于 SQL 表达式
可以在查询时修改。对于此用例,SQLAlchemy 提供了
with_expression()
加载器选项,当与映射器级别 query_expression()
指令结合使用时,可能会产生此结果。
要将 with_expression()
应用于查询,映射的类必须使用 query_expression()
预先配置 ORM 映射属性
命令;该指令将在映射的
类,该类适用于接收查询时 SQL 表达式。 下面
我们向 User
添加了一个新的属性 User.book_count
。此 ORM 映射属性是只读的,没有默认值;在加载的实例上访问它通常会生成 None
:
>>> from sqlalchemy.orm import query_expression
>>> class User(Base):
... __tablename__ = "user_account"
... id: Mapped[int] = mapped_column(primary_key=True)
... name: Mapped[str]
... fullname: Mapped[Optional[str]]
... book_count: Mapped[int] = query_expression()
...
... def __repr__(self) -> str:
... return f"User(id={self.id!r}, name={self.name!r}, fullname={self.fullname!r})"
在映射中配置 User.book_count
属性后,我们可以填充
it 替换为来自 SQL 表达式的数据,使用
with_expression()
加载器选项,在加载时将自定义 SQL 表达式应用于每个 User
对象:
>>> from sqlalchemy.orm import with_expression
>>> stmt = (
... select(User)
... .join_from(User, Book)
... .group_by(Book.owner_id)
... .options(with_expression(User.book_count, func.count(Book.id)))
... )
>>> for user in session.scalars(stmt):
... print(f"Username: {user.name} Number of books: {user.book_count}")
SELECT count(book.id) AS count_1, user_account.id, user_account.name,
user_account.fullname
FROM user_account JOIN book ON user_account.id = book.owner_id
GROUP BY book.owner_id
[...] ()
Username: spongebob Number of books: 3
Username: sandy Number of books: 3
在上面,我们将 func.count(Book.id)
表达式从 select()
结构的 columns 参数中移出,并移到 with_expression()
中
loader 选项。 然后,ORM 将此视为特殊柱载荷
选项,该选项将动态应用于语句。
query_expression()
映射有以下注意事项:
在未使用with_expression()
填充的对象上 属性,则对象实例上的属性将具有值None
,除非在映射query_expression.default_expr
parameter 设置为默认 SQL 表达式。with_expression()
值不会填充到以下对象上 已加载,除非使用 Populate Existing (填充现有项)。下面的示例将不起作用,因为A
对象已经加载:# load the first A obj = session.scalars(select(A).order_by(A.id)).first() # load the same A with an option; expression will **not** be applied # to the already-loaded object obj = session.scalars(select(A).options(with_expression(A.expr, some_expr))).first()
要确保在现有对象上重新加载该属性,请使用 Populate Existing execution 选项以确保重新填充所有列:obj = session.scalars( select(A) .options(with_expression(A.expr, some_expr)) .execution_options(populate_existing=True) ).first()
with_expression当
对象 过期。一旦对象过期,通过Session.expire()
或通过Session.commit()
的 expire_on_commit 行为,SQL 表达式及其值不再与属性关联,并将在后续访问中返回None
。with_expression()
作为对象加载选项,只对最外层生效 的查询,并且仅适用于针对完整实体的查询,而不适用于子查询中的任意列选择,或者是复合语句(如 UNION)的元素。有关示例,请参阅下一节 将 with_expression() 与 UNION 一起使用,其他子查询。
mapped 属性不能应用于查询的其他部分,例如 WHERE 子句、ORDER BY 子句,并且不能使用 ad-hoc 表达式;也就是说,这不起作用:# can't refer to A.expr elsewhere in the query stmt = ( select(A) .options(with_expression(A.expr, A.x + A.y)) .filter(A.expr > 5) .order_by(A.expr) )
A.expr
表达式将在上面的 WHERE 子句和 ORDER BY 子句中解析为 NULL。要在整个查询中使用表达式,请赋值给一个变量并使用该表达式:# assign desired expression up front, then refer to that in # the query a_expr = A.x + A.y stmt = ( select(A) .options(with_expression(A.expr, a_expr)) .filter(a_expr > 5) .order_by(a_expr) )
另请参阅
with_expression()
选项是一个特殊选项,用于在查询时动态地将 SQL 表达式应用于映射的类。有关在映射器上配置的普通固定 SQL 表达式,请参阅作为映射属性的 SQL 表达式部分。
将 with_expression()
与 UNION 一起使用,其他子查询¶
with_expression()
结构是一个 ORM 加载器选项,因此只能应用于 SELECT 语句的最外层,即加载特定的 ORM 实体。如果在 select()
中使用,它不会有任何效果,然后将用作子查询或复合语句(如 UNION)中的元素。
为了在子查询中使用任意 SQL 表达式,应使用常规的 Core 样式添加表达式的方法。要将子查询派生的表达式组装到 ORM 实体的 query_expression()
属性上,
with_expression()
用于 ORM 对象加载的顶层,引用子查询中的 SQL 表达式。
在下面的示例中,对 ORM 实体 A
使用了两个 select()
结构,并在
expr
结合使用,并使用 union_all()
进行组合。然后,在最顶层,使用从 UNION 和其他集合作中选择实体中描述的查询技术,从此 UNION 中选择 A
实体,添加一个带有 with_expression()
的选项,以将此 SQL 表达式提取到新加载的 A
实例上:
>>> from sqlalchemy import union_all
>>> s1 = (
... select(User, func.count(Book.id).label("book_count"))
... .join_from(User, Book)
... .where(User.name == "spongebob")
... )
>>> s2 = (
... select(User, func.count(Book.id).label("book_count"))
... .join_from(User, Book)
... .where(User.name == "sandy")
... )
>>> union_stmt = union_all(s1, s2)
>>> orm_stmt = (
... select(User)
... .from_statement(union_stmt)
... .options(with_expression(User.book_count, union_stmt.selected_columns.book_count))
... )
>>> for user in session.scalars(orm_stmt):
... print(f"Username: {user.name} Number of books: {user.book_count}")
SELECT user_account.id, user_account.name, user_account.fullname, count(book.id) AS book_count
FROM user_account JOIN book ON user_account.id = book.owner_id
WHERE user_account.name = ?
UNION ALL
SELECT user_account.id, user_account.name, user_account.fullname, count(book.id) AS book_count
FROM user_account JOIN book ON user_account.id = book.owner_id
WHERE user_account.name = ?
[...] ('spongebob', 'sandy')
Username: spongebob Number of books: 3
Username: sandy Number of books: 3
列加载 API¶
对象名称 |
描述 |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-
函数 sqlalchemy.orm 中。defer(key:Literal['*']QueryableAttribute[Any], *addl_attrs:Literal['*']QueryableAttribute[Any], raiseload: bool = False)_AbstractLoad ¶
指示应延迟给定的面向列的属性,例如,在访问之前不加载。
此函数是Load
接口的一部分,支持方法链式和独立作。
例如:from sqlalchemy.orm import defer session.query(MyClass).options( defer(MyClass.attribute_one), defer(MyClass.attribute_two) )
要在相关类上指定属性的延迟加载,可以一次指定一个标记的路径,并指定链上每个链接的加载样式。要保持链接的加载样式不变,请使用defaultload():
session.query(MyClass).options( defaultload(MyClass.someattr).defer(RelatedClass.some_column) )
可以使用Load.options()
一次捆绑与关系相关的多个延迟选项:select(MyClass).options( defaultload(MyClass.someattr).options( defer(RelatedClass.some_column), defer(RelatedClass.some_other_column), defer(RelatedClass.another_column), ) )
参数
key¶- 要延迟的属性。
raiseload¶—— 在访问 deferred 属性时引发InvalidRequestError
而不是延迟加载值。用于防止发出不需要的 SQL。
在 1.4 版本加入.
-
函数 sqlalchemy.orm 中。deferred(column: _ORMColumnExprArgument[_T], *additional_columns: _ORMColumnExprArgument[Any], group:strNone=None, raiseload: bool = False, comparator_factory:Type[PropComparator[_T]]None=None, init:_NoArgbool=_NoArg.NO_ARG, repr:_NoArgbool=_NoArg.NO_ARG, default:AnyNone=_NoArg.NO_ARG, default_factory:_NoArgCallable[[],_T]=_NoArg.NO_ARG, compare:_NoArgbool=_NoArg.NO_ARG, kw_only:_NoArgbool=_NoArg.NO_ARG, hash:_NoArgboolNone=_NoArg.NO_ARG, active_history: bool = False, expire_on_flush: bool = True, info:_InfoTypeNone=None, doc:strNone=None)MappedSQLExpression[_T] ¶
指示基于列的映射属性,默认情况下,除非访问,否则不会加载该属性。
当使用mapped_column() 时
,通过使用mapped_column.deferred
参数。
参数
其他参数与column_property()
相同。
-
函数 sqlalchemy.orm 中。query_expression(default_expr: _ORMColumnExprArgument[_T] = <sqlalchemy.sql.elements.Null object>, *, repr: Union[_NoArg, bool] = _NoArg.NO_ARG, 比较: Union[_NoArg, bool] = _NoArg.NO_ARG expire_on_flush: bool = True, info: 可选[_InfoType] = 无,文档: 可选[str] = 无)MappedSQLExpression[_T] ¶
指示从查询时 SQL 表达式填充的属性。
参数
default_expr¶– 可选的 SQL 表达式对象,如果以后没有使用with_expression()
分配,则在所有情况下都将使用。
在 1.2 版本加入.
另请参阅
将任意 SQL 表达式加载到对象上 - 背景和使用示例
-
函数 sqlalchemy.orm 中。load_only(*attrs:Literal['*']QueryableAttribute[Any], raiseload: bool = False)_AbstractLoad ¶
指示对于特定实体,只应加载给定的基于列的属性名称列表;所有其他的都将被推迟。
此函数是Load
接口的一部分,支持方法链式和独立作。
示例 — 给定一个类User
,仅加载name
和fullname
属性:session.query(User).options(load_only(User.name, User.fullname))
示例 — 给定关系User.addresses -> Address
,为User.addresses
集合指定子查询加载,但在每个Address
对象仅加载email_address
属性:session.query(User).options( subqueryload(User.addresses).load_only(Address.email_address) )
对于具有多个实体的语句,可以使用Load
构造函数专门引用潜在顾客实体:stmt = ( select(User, Address) .join(User.addresses) .options( Load(User).load_only(User.name, User.fullname), Load(Address).load_only(Address.email_address), ) )
与 populate_existing 执行选项中,仅刷新列出的属性。
参数
attrs¶—— 要加载的属性,所有其他属性都将被延迟。raiseload¶ –
引发InvalidRequestError
而不是在访问 deferred 属性时延迟加载值。用于防止发出不需要的 SQL。
2.0 版的新Function。
另请参阅
参数
attrs¶—— 要加载的属性,所有其他属性都将被延迟。raiseload¶ –
引发InvalidRequestError
而不是在访问 deferred 属性时延迟加载值。用于防止发出不需要的 SQL。
2.0 版的新Function。
-
函数 sqlalchemy.orm 中。undefer(key:Literal['*']QueryableAttribute[Any], *addl_attrs:Literal['*']QueryableAttribute[Any]_AbstractLoad ¶
指示给定的面向列的属性应该是无延迟的,例如,在整个实体的 SELECT 语句中指定。
未延迟的列通常在映射上设置为deferred()
属性。
此函数是Load
接口的一部分,支持方法链式和独立作。
例子:# undefer two columns session.query(MyClass).options( undefer(MyClass.col1), undefer(MyClass.col2) ) # undefer all columns specific to a single class using Load + * session.query(MyClass, MyOtherClass).options(Load(MyClass).undefer("*")) # undefer a column on a related object select(MyClass).options(defaultload(MyClass.items).undefer(MyClass.text))
参数
key¶- 要取消延迟的属性。
-
函数 sqlalchemy.orm 中。undefer_group(name: str)_AbstractLoad ¶
指示给定延迟组名称中的列应为 undeferred。
未延迟的列在映射上设置为deferred()
属性,并包含一个 “group” 名称。
例如:session.query(MyClass).options(undefer_group("large_attrs"))
要取消延迟相关实体上的一组属性,路径可以是 使用关系加载器选项拼写出来,例如defaultload()
中:select(MyClass).options( defaultload("someattr").undefer_group("large_attrs") )
-
函数 sqlalchemy.orm 中。with_expression(key: _AttrType, expression: _ColumnExpressionArgument[Any])_AbstractLoad ¶
将临时 SQL 表达式应用于 “deferred expression” 属性。
此选项与query_expression()
映射器级别的构造,该构造指示应作为临时 SQL 表达式目标的属性。
例如:stmt = select(SomeClass).options( with_expression(SomeClass.x_y_expr, SomeClass.x + SomeClass.y) )
在 1.2 版本加入.
另请参阅
将任意 SQL 表达式加载到对象上 - 背景和使用示例