本节介绍有关加载列的其他选项。
此功能允许仅在直接访问时加载表的特定列,而不允许使用 Query
. 当您不想在不需要时将一个大文本或二进制字段加载到内存中时,此功能非常有用。单独的列可以自己惰性加载,也可以使用 orm.deferred()
将它们标记为“延期”的函数。在下面的示例中,我们定义了一个映射,该映射将加载 .excerpt
和 .photo
在单独的单行select语句中,当每个属性首次在单个对象实例上引用时:
from sqlalchemy.orm import deferred
from sqlalchemy import Integer, String, Text, Binary, Column
class Book(Base):
__tablename__ = 'book'
book_id = Column(Integer, primary_key=True)
title = Column(String(200), nullable=False)
summary = Column(String(2000))
excerpt = deferred(Column(Text))
photo = deferred(Column(Binary))
经典映射总是使用 orm.deferred()
在 properties
字典对照表绑定 Column
::
mapper(Book, book_table, properties={
'photo':deferred(book_table.c.photo)
})
延迟的列可以与一个“组”名称相关联,以便在第一次访问它们中的任何一个时将它们加载在一起。下面的示例定义了一个带有 photos
延期组。当一 .photo
访问后,所有三张照片都将加载到一个select语句中。这个 .excerpt
访问时将单独加载::
class Book(Base):
__tablename__ = 'book'
book_id = Column(Integer, primary_key=True)
title = Column(String(200), nullable=False)
summary = Column(String(2000))
excerpt = deferred(Column(Text))
photo1 = deferred(Column(Binary), group='photos')
photo2 = deferred(Column(Binary), group='photos')
photo3 = deferred(Column(Binary), group='photos')
您可以在 Query
级别使用选项,包括 orm.defer()
和 orm.undefer()
::
from sqlalchemy.orm import defer, undefer
query = session.query(Book)
query = query.options(defer('summary'))
query = query.options(undefer('excerpt'))
query.all()
orm.deferred()
用“group”标记的属性可以使用 orm.undefer_group()
,以组名发送:
from sqlalchemy.orm import undefer_group
query = session.query(Book)
query.options(undefer_group('photos')).all()
可以选择任意列集作为“仅加载”列,该列将在延迟给定实体上的所有其他列时加载,使用 orm.load_only()
::
from sqlalchemy.orm import load_only
session.query(Book).options(load_only("summary", "excerpt"))
0.9.0 新版功能.
在 Query
它加载多种类型的实体, Load
对象可以指定以哪个父实体开头::
from sqlalchemy.orm import Load
query = session.query(Book, Author).join(Book.author)
query = query.options(
Load(Book).load_only("summary", "excerpt"),
Load(Author).defer("bio")
)
要沿着各种关系的路径指定列延迟选项,选项支持链接,其中首先指定每个关系的加载样式,然后链接到延迟选项。例如,加载 Book
实例,然后加入热切加载 Author
,然后将延迟选项应用于 Author
单位:
from sqlalchemy.orm import joinedload
query = session.query(Book)
query = query.options(
joinedload(Book.author).load_only("summary", "excerpt"),
)
如果父关系的加载样式应保持不变,请使用 orm.defaultload()
::
from sqlalchemy.orm import defaultload
query = session.query(Book)
query = query.options(
defaultload(Book.author).load_only("summary", "excerpt"),
)
0.9.0 新版功能: 支持 Load
以及其他可以更好地确定延期期权目标的期权。
sqlalchemy.orm.
defer
(key, *addl_attrs)¶指示给定的列定向属性应延迟,例如,在访问之前不加载。
此函数是 Load
接口和支持方法链接和独立操作。
例如。::
from sqlalchemy.orm import defer
session.query(MyClass).options(
defer("attribute_one"),
defer("attribute_two"))
session.query(MyClass).options(
defer(MyClass.attribute_one),
defer(MyClass.attribute_two))
要在相关类上指定属性的延迟加载,可以一次指定一个令牌的路径,为链上的每个链接指定加载样式。若要保持链接的加载样式不变,请使用 orm.defaultload()
::
session.query(MyClass).options(defaultload("someattr").defer("some_column"))
A Load
存在于某个路径上的对象可以具有 Load.defer()
多次调用,每个都将在同一父实体上操作:
session.query(MyClass).options(
defaultload("someattr").
defer("some_column").
defer("some_other_column").
defer("another_column")
)
key¶ -- 要延迟的属性。
*addl_attrs¶ -- 此选项支持将路径指定为一系列属性的旧0.8样式,现在由方法链接样式取代。…已弃用::0.9 * Advl orm.defer()
已弃用,将在将来的版本中删除。请将方法链接与defaultLoad()一起使用以指示路径。
sqlalchemy.orm.
deferred
(*columns, **kw)¶指示一个基于列的映射属性,默认情况下,除非访问该属性,否则不会加载该属性。
**kw¶ -- 传递给的其他关键字参数 ColumnProperty
.
参见
sqlalchemy.orm.
query_expression
()¶指示从查询时SQL表达式填充的属性。
1.2 新版功能.
参见
mapper_query_expression
sqlalchemy.orm.
load_only
(*attrs)¶指示对于特定实体,只应加载基于列的属性名的给定列表;所有其他属性名都将被延迟。
此函数是 Load
接口和支持方法链接和独立操作。
示例-给定一个类 User
只加载 name
和 fullname
属性::
session.query(User).options(load_only("name", "fullname"))
示例-给定关系 User.addresses -> Address
,为指定子查询加载 User.addresses
收集,但在每个 Address
对象仅加载 email_address
属性:
session.query(User).options(
subqueryload("addresses").load_only("email_address")
)
对于一个 Query
如果有多个实体,则可以使用 Load
施工人员:
session.query(User, Address).join(User.addresses).options(
Load(User).load_only("name", "fullname"),
Load(Address).load_only("email_addres")
)
0.9.0 新版功能.
sqlalchemy.orm.
undefer
(key, *addl_attrs)¶指示给定的面向列的属性应取消引用,例如,在整个实体的select语句中指定。
未被检索的列通常在映射上设置为 deferred()
属性。
此函数是 Load
接口和支持方法链接和独立操作。
实例:
# undefer two columns
session.query(MyClass).options(undefer("col1"), undefer("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
session.query(MyClass).options(
defaultload(MyClass.items).undefer('text'))
key¶ -- 属性未被检索。
*addl_attrs¶ -- 此选项支持将路径指定为一系列属性的旧0.8样式,现在由方法链接样式取代。…已弃用::0.9 * Advl orm.undefer()
已弃用,将在将来的版本中删除。请将方法链接与defaultLoad()一起使用以指示路径。
sqlalchemy.orm.
undefer_group
(name)¶指示应取消对给定延迟组名称中的列的检索。
在映射上未被检索的列设置为 deferred()
属性并包含“组”名称。
例如::
session.query(MyClass).options(undefer_group("large_attrs"))
要取消对相关实体的一组属性的传递,可以使用关系加载器选项(如 orm.defaultload()
::
session.query(MyClass).options(
defaultload("someattr").undefer_group("large_attrs"))
在 0.9.0 版更改: orm.undefer_group()
现在特定于特定的实体加载路径。
sqlalchemy.orm.
with_expression
(key, expression)¶将临时SQL表达式应用于“deferred expression”属性。
此选项与 orm.query_expression()
映射器级构造,指示应作为临时SQL表达式目标的属性。
例如。::
sess.query(SomeClass).options(
with_expression(SomeClass.x_y_expr, SomeClass.x + SomeClass.y)
)
1.2 新版功能.
参见
mapper_query_expression
这个 Bundle
可用于查询一个命名空间下的列组。
0.9.0 新版功能.
绑定允许将列分组在一起::
from sqlalchemy.orm import Bundle
bn = Bundle('mybundle', MyClass.data1, MyClass.data2)
for row in session.query(bn).filter(bn.c.data1 == 'd1'):
print(row.mybundle.data1, row.mybundle.data2)
可以对包进行子类化,以便在获取结果时提供自定义行为。方法 Bundle.create_row_processor()
给出了 Query
以及一组在查询执行时的“行处理器”功能;这些处理器功能在给定结果行时将返回单个属性值,然后这些属性值可以适应任何类型的返回数据结构。下面说明了如何替换 KeyedTuple
使用纯python字典返回结构:
from sqlalchemy.orm import Bundle
class DictBundle(Bundle):
def create_row_processor(self, query, procs, labels):
"""Override create_row_processor to return values as dictionaries"""
def proc(row):
return dict(
zip(labels, (proc(row) for proc in procs))
)
return proc
在 1.0 版更改: 这个 proc()
Callable传递给 create_row_processor()
自定义方法 Bundle
类现在只接受一个“row”参数。
上述包的结果将返回字典值:
bn = DictBundle('mybundle', MyClass.data1, MyClass.data2)
for row in session.query(bn).filter(bn.c.data1 == 'd1'):
print(row.mybundle['data1'], row.mybundle['data2'])
这个 Bundle
构造也集成到 composite()
,用于在作为单个属性查询时将复合属性作为对象返回。