列加载选项


关于本文档


本节介绍有关列加载的其他选项。使用的映射包括存储大字符串值的列,我们可能希望在加载它们时对其进行限制。


查看此页面的 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.idbook.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() 选项同时应用于 UserBook,我们将使用两个单独的选项:

>>> 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 的查询将自动不包含 summarycover_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})"


使用上述映射,访问 summarycover_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


对象名称

描述


defer(键, *addl_attrs, [raiseload])


指示应延迟给定的面向列的属性,例如,在访问之前不加载。


deferred(column, *additional_columns, [group, raiseload, comparator_factory, init, repr, default, default_factory, compare, kw_only, hash, active_history, expire_on_flush, info, doc])


指示基于列的映射属性,默认情况下,除非访问,否则不会加载该属性。


load_only(*attrs, [raiseload])


指示对于特定实体,只应加载给定的基于列的属性名称列表;所有其他的都将被推迟。


query_expression([default_expr], *, [repr, compare, expire_on_flush, info, doc])


指示从查询时 SQL 表达式填充的属性。


undefer(键, *addl_attrs)


指示给定的面向列的属性应该是无延迟的,例如,在整个实体的 SELECT 语句中指定。


undefer_group(名称)


指示给定延迟组名称中的列应为 undeferred。


with_expression(键、表达式)


将临时 SQL 表达式应用于 “deferred expression” 属性。


函数 sqlalchemy.orm 中。deferkey: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 中。deferredcolumn _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 = Falseexpire_on_flush: bool = True, info:_InfoTypeNone=None, doc:strNone=None MappedSQLExpression[_T]


指示基于列的映射属性,默认情况下,除非访问,否则不会加载该属性。


当使用 mapped_column() 时,通过使用 mapped_column.deferred 参数。


参数

  • *columns —— 要映射的列。 这通常是单个 Column 对象,但是支持集合以支持在同一属性下映射的多个列。

  • raiseload


    boolean(如果为 True),则表示如果要执行 load作,则应引发异常。


    在 1.4 版本加入.


其他参数与 column_property() 相同。


函数 sqlalchemy.orm 中。query_expressiondefault_expr: _ORMColumnExprArgument[_T] = <sqlalchemy.sql.elements.Null object>*repr: Union[_NoArgbool] = _NoArg.NO_ARG比较: Union[_NoArgbool] = _NoArg.NO_ARG expire_on_flush: bool = Trueinfo: 可选[_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,仅加载 namefullname 属性:

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 中。undeferkey: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_groupname 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_expressionkey _AttrTypeexpression _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 版本加入.


参数

  • key– 要填充的属性


  • expr- 要应用于属性的 SQL 表达式。


另请参阅


将任意 SQL 表达式加载到对象上 - 背景和使用示例