版本:1.1.0b2 |发布日期:2016年7月1日

SQLAlchemy 1.1文档

加载列

本节介绍有关加载色谱柱的其他选项。

延迟列加载

这个特性允许一个表的特定列只能在直接访问时被加载,而不是在使用Query查询实体的时候。这个功能在有人想避免把无用但又很大的text字段或者二进制字段加载到内存时十分有效可以使用orm.deferred()函数将各列标记为“延迟”,从而可以将各个列自行加载,也可以将它们放入到一起加载的组中。在下面的例子中,我们定义了一个映射,当个人第一次引用每个属性时,将在单独的单行SELECT语句中加载.excerpt.photo对象实例:

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')

您可以使用包括orm.defer()orm.undefer()的选项来延迟或取消Query

from sqlalchemy.orm import defer, undefer

query = session.query(Book)
query = query.options(defer('summary'))
query = query.options(undefer('excerpt'))
query.all()

orm.deferred() attributes which are marked with a “group” can be undeferred using orm.undefer_group(), sending in the group name:

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实例,然后加入-eager-加载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和其他选项,可以更好地定位延迟选项。

列递延API

sqlalchemy.orm.deferred(*columns, **kw)

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

参数:
  • *列 - 要映射的列。这通常是一个Column对象,但是为了支持在同一个属性下映射多个列,支持一个集合。
  • **kw – additional keyword arguments passed to ColumnProperty.
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 object that is present on a certain path can have Load.defer() called multiple times, each will operate on the same parent entity:

session.query(MyClass).options(
                defaultload("someattr").
                    defer("some_column").
                    defer("some_other_column").
                    defer("another_column")
    )
参数:
  • - 待延期的属性。
  • * addl_attrs - 弃用;这个选项支持将旧的0.8风格的路径指定为一系列的属性,现在被方法链接的风格所取代。
sqlalchemy.orm。 T0> LOAD_ONLY T1> ( T2> * ATTRS T3> ) T4> ¶ T5>

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

这个函数是Load接口的一部分,支持方法链接和独立操作。

示例 - 给定类User,仅加载namefullname属性:

session.query(User).options(load_only("name", "fullname"))

Example - given a relationship User.addresses -> Address, specify subquery loading for the User.addresses collection, but on each Address object load only the email_address attribute:

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("*"))
参数:
  • - 要被取消的属性。
  • * addl_attrs - 弃用;这个选项支持将旧的0.8风格的路径指定为一系列的属性,现在被方法链接的风格所取代。
sqlalchemy.orm。 T0> undefer_group T1> ( T2> 名称 T3> ) T4> ¶ T5 >

指出给定的延期组名称中的列应该是未定的。

未定位的列在映射上设置为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()现在特定于一个分立的实体加载路径。

列包

可以使用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和一组“行处理器”这些处理函数在给出一个结果行的时候会返回个别的属性值,然后可以适应任何类型的返回数据结构。下面的例子说明用直接的Python字典替换通常的KeyedTuple返回结构:

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()可调用传递给现在定制Bundle类的create_row_processor()方法只接受一个“行”参数。

上述包的结果将返回字典值:

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()的行为中,用于在作为单独属性查询时将组合属性作为对象返回。