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

SQLAlchemy 1.1文档

收集配置和技术

relationship()函数定义两个类之间的链接。当链接定义了一对多或多对多的关系时,当对象被加载和操作时,它被表示为一个Python集合。本节介绍有关收集配置和技术的其他信息。

处理大集合

根据关系的加载策略,relationship()的默认行为是完全加载项中的集合。另外,默认情况下,Session只知道如何删除会话中实际存在的对象。当一个父实例被标记为删除和刷新时,Session加载其子项的完整列表,以便它们可以被删除,或者将其外键值设置为空;这是为了避免违反约束。对于大量的子项目,有几种策略可以避免在加载时间和删除时间内全部加载子项目。

动态关系加载器

所谓的“动态”关系是能够管理大型集合的关键特征。这是relationship()的一种可选形式,它在访问时返回一个Query对象来代替集合。filter() criterion may be applied as well as limits and offsets, either explicitly or via array slices:

class User(Base):
    __tablename__ = 'user'

    posts = relationship(Post, lazy="dynamic")

jack = session.query(User).get(id)

# filter Jack's blog posts
posts = jack.posts.filter(Post.headline=='this is a post')

# apply array slices
posts = jack.posts[5:20]

动态关系通过append()remove()方法支持有限的写入操作:

oldpost = jack.posts.filter(Post.headline=='old post').one()
jack.posts.remove(oldpost)

jack.posts.append(Post('new post'))

由于动态关系的读取端总是查询数据库,因此在对数据进行刷新之前,对底层集合的更改将不可见。但是,只要在使用中的Session上启用了“autoflush”,每当集合即将发出查询时,都会自动发生。

要在后端参考上放置一个动态关系,请结合lazy='dynamic'使用backref()函数:

class Post(Base):
    __table__ = posts_table

    user = relationship(User,
                backref=backref('posts', lazy='dynamic')
            )

请注意,此时,激活/延迟加载选项不能结合使用动态关系。

注意

dynamic_loader()函数基本上与relationship()指定的lazy='dynamic'参数相同。

警告

“动态”加载器仅适用于集合使用具有多对一,一对一或uselist = False关系的“动态”加载器是无效的。在这些情况下,较新版本的SQLAlchemy会发出警告或异常。

设置Noload,RaiseLoad

即使访问,“noload”关系也不会从数据库加载。它使用lazy='noload'配置:

class MyClass(Base):
    __tablename__ = 'some_table'

    children = relationship(MyOtherClass, lazy='noload')

上面,children集合是完全可写的,对它的更改将被保存到数据库中,并且在添加时可以在本地读取。但是,当MyClass的实例刚刚从数据库加载时,children集合保持为空。也可以使用orm.noload()加载器选项在查询选项基础上提供noload策略。

或者,“加载”加载的关系将引发一个InvalidRequestError,其中属性通常会发出延迟加载:

class MyClass(Base):
    __tablename__ = 'some_table'

    children = relationship(MyOtherClass, lazy='raise')

如上所述,children集合上的属性访问将会引发一个异常,如果它以前没有被预先加载的话。这包括读取权限,但是对于集合也会影响写入权限,因为集合不能在没有先加载的情况下进行变异。这样做的基本原理是确保应用程序在特定的上下文中不发出任何意外的延迟加载。而不是必须通过SQL日志读取以确定所有必要的属性是急切加载,“提高”策略将导致卸载属性立即提高,如果访问。通过使用orm.raiseload()加载器选项的查询选项,也可以使用提升策略。

版本1.1新增:添加了“提升”加载器策略。

使用被动删除

使用passive_deletes禁用DELETE操作上的子对象加载,并结合数据库上的“ON DELETE(CASCADE | SET NULL)”自动级联删除子对象:

class MyClass(Base):
    __tablename__ = 'mytable'
    id = Column(Integer, primary_key=True)
    children = relationship("MyOtherClass",
                    cascade="all, delete-orphan",
                    passive_deletes=True)

class MyOtherClass(Base):
    __tablename__ = 'myothertable'
    id = Column(Integer, primary_key=True)
    parent_id = Column(Integer,
                ForeignKey('mytable.id', ondelete='CASCADE')
                    )

注意

要使用“ON DELETE CASCADE”,底层数据库引擎必须支持外键。

当应用passive_deletes时,当MyClass的实例标记为删除时,children关系不会被加载到内存中。The cascade="all, delete-orphan" will take effect for instances of MyOtherClass which are currently present in the session; however for instances of MyOtherClass which are not loaded, SQLAlchemy assumes that “ON DELETE CASCADE” rules will ensure that those rows are deleted by the database.

也可以看看

orm.mapper.passive_deletes - similar feature on mapper()

自定义集合访问

映射一对多或多对多关系会导致通过父实例上的属性访问值的集合。默认情况下,这个集合是一个list

class Parent(Base):
    __tablename__ = 'parent'
    parent_id = Column(Integer, primary_key=True)

    children = relationship(Child)

parent = Parent()
parent.children.append(Child())
print(parent.children[0])

集合不限于列表。通过在relationship()中指定collection_class选项,可以使用集合,可变序列和几乎任何可以充当容器的Python对象来代替默认列表:

class Parent(Base):
    __tablename__ = 'parent'
    parent_id = Column(Integer, primary_key=True)

    # use a set
    children = relationship(Child, collection_class=set)

parent = Parent()
child = Child()
parent.children.add(child)
assert child in parent.children

词典集合

使用字典作为集合时,需要一些额外的细节。这是因为对象总是作为列表从数据库加载,并且必须提供密钥生成策略才能正确填充字典。attribute_mapped_collection()函数是实现简单字典集合的最常用的方法。它生成一个字典类,将映射类的特定属性作为关键字。下面我们映射一个Item类,其中包含键入到Note.keyword属性的Note项的字典:

from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship
from sqlalchemy.orm.collections import attribute_mapped_collection
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class Item(Base):
    __tablename__ = 'item'
    id = Column(Integer, primary_key=True)
    notes = relationship("Note",
                collection_class=attribute_mapped_collection('keyword'),
                cascade="all, delete-orphan")

class Note(Base):
    __tablename__ = 'note'
    id = Column(Integer, primary_key=True)
    item_id = Column(Integer, ForeignKey('item.id'), nullable=False)
    keyword = Column(String)
    text = Column(String)

    def __init__(self, keyword, text):
        self.keyword = keyword
        self.text = text

Item.notes is then a dictionary:

>>> item = Item()
>>> item.notes['a'] = Note('a', 'atext')
>>> item.notes.items()
{'a': <__main__.Note object at 0x2eaaf0>}

attribute_mapped_collection()将确保每个Note.keyword属性符合字典中的键。例如,当分配给Item.notes时,我们提供的字典键必须与实际的Note对象匹配:

item = Item()
item.notes = {
            'a': Note('a', 'atext'),
            'b': Note('b', 'btext')
        }

attribute_mapped_collection()用作键的属性根本不需要映射!Using a regular Python @property allows virtually any detail or combination of details about the object to be used as the key, as below when we establish it as a tuple of Note.keyword and the first ten letters of the Note.text field:

class Item(Base):
    __tablename__ = 'item'
    id = Column(Integer, primary_key=True)
    notes = relationship("Note",
                collection_class=attribute_mapped_collection('note_key'),
                backref="item",
                cascade="all, delete-orphan")

class Note(Base):
    __tablename__ = 'note'
    id = Column(Integer, primary_key=True)
    item_id = Column(Integer, ForeignKey('item.id'), nullable=False)
    keyword = Column(String)
    text = Column(String)

    @property
    def note_key(self):
        return (self.keyword, self.text[0:10])

    def __init__(self, keyword, text):
        self.keyword = keyword
        self.text = text

上面我们添加了一个Note.item backref。赋值给这个反向关系时,Note被添加到Item.notes字典中,并自动为我们生成密钥:

>>> item = Item()
>>> n1 = Note("a", "atext")
>>> n1.item = item
>>> item.notes
{('a', 'atext'): <__main__.Note object at 0x2eaaf0>}

其他内置的字典类型包括column_mapped_collection(),除了Column对象外,它几乎类似于attribute_mapped_collection()

from sqlalchemy.orm.collections import column_mapped_collection

class Item(Base):
    __tablename__ = 'item'
    id = Column(Integer, primary_key=True)
    notes = relationship("Note",
                collection_class=column_mapped_collection(Note.__table__.c.keyword),
                cascade="all, delete-orphan")

以及传递任何可调用函数的mapped_collection()请注意,如前所述,通常使用attribute_mapped_collection()@property更容易:

from sqlalchemy.orm.collections import mapped_collection

class Item(Base):
    __tablename__ = 'item'
    id = Column(Integer, primary_key=True)
    notes = relationship("Note",
                collection_class=mapped_collection(lambda note: note.text[0:10]),
                cascade="all, delete-orphan")

字典映射通常与“Association Proxy”扩展结合使用,以产生流线化的字典视图。有关示例,请参阅Proxying to Dictionary Based CollectionsComposite Association Proxies

sqlalchemy.orm.collections。 T0> attribute_mapped_collection T1> ( T2> attr_name T3> ) T4>

基于属性的键控的基于字典的集合类型。

使用基于集合中实体的“attr_name”属性的键值返回MappedCollection工厂,其中attr_name是属性的字符串名称。

键值在对象的生命周期中必须是不可变的。例如,如果这些键值在会话期间将发生更改(即在会话刷新后从无到数据库分配的整数),则无法映射外键值。

sqlalchemy.orm.collections。 T0> column_mapped_collection T1> ( T2> mapping_spec T3> ) T4>

基于列的键控的基于字典的集合类型。

使用从mapping_spec生成的键控函数返回一个MappedCollection工厂,该工具可能是一列或一列列。

键值在对象的生命周期中必须是不可变的。例如,如果这些键值在会话期间将发生更改(即在会话刷新后从无到数据库分配的整数),则无法映射外键值。

sqlalchemy.orm.collections。 T0> mapped_collection T1> ( T2> keyfunc T3> ) T4>

基于字典的具有任意键控的集合类型。

返回一个带有从keyfunc生成的键控函数的MappedCollection工厂,这是一个可调用的实体并返回一个键值。

键值在对象的生命周期中必须是不可变的。例如,如果这些键值在会话期间将发生更改(即在会话刷新后从无到数据库分配的整数),则无法映射外键值。

自定义集合实现

您也可以将自己的类型用于收藏。在简单情况下,从listset中添加自定义行为是所需要的。在其他情况下,需要特殊的装饰器来告诉SQLAlchemy有关集合如何操作的更多细节。

我是否需要自定义收集实现?

在大多数情况下,根本不是!“自定义”集合最常见的用例是将传入的值验证或编组为新的表单,如成为类实例的字符串,或者以某种方式在内部表示数据的字符串,以不同的形式在外面呈现这些数据的“视图”。

对于第一个用例来说,orm.validates()装饰器是迄今为止在所有情况下为了验证和简单编组而截取传入值的最简单的方法。有关这方面的示例,请参见Simple Validators

For the second use case, the Association Proxy extension is a well-tested, widely used system that provides a read/write “view” of a collection in terms of some attribute present on the target object. 由于目标属性可以是返回几乎任何东西的@property,因此只需几个函数就可以构建一个集合的“替代”视图。这种方法使底层的映射集合不受影响,并避免了在逐个方法的基础上仔细调整集合行为的需要。

当集合需要在访问或变异操作上有特殊行为时,定制集合非常有用,否则这些操作无法在集合的外部建模。他们当然可以结合上述两种方法。

SQLAlchemy中的集合是透明的检测仪表意味着对集合上的正常操作进行跟踪,并导致在刷新时间将更改写入数据库。另外,收集操作可以触发事件,这指示必须发生一些次要操作。辅助操作的例子包括将子项保存在父节点Session(即save-update级联)中,以及同步双向关系的状态即一个backref())。

collections包理解list,sets和dicts的基本接口,并会自动将instrumentation应用于这些内置类型及其子类。实现基本集合接口的对象派生类型通过鸭式输入进行检测和检测:

class ListLike(object):
    def __init__(self):
        self.data = []
    def append(self, item):
        self.data.append(item)
    def remove(self, item):
        self.data.remove(item)
    def extend(self, items):
        self.data.extend(items)
    def __iter__(self):
        return iter(self.data)
    def foo(self):
        return 'foo'

appendremoveextend是已知的类列表方法,并将自动进行检测。__iter__不是一个变异方法,不会被检测,而且foo也不会。

当然,鸭式输入(即猜测)并不是坚如磐石的,所以你可以通过提供一个__emulates__ class属性来明确你正在实现的接口:

class SetLike(object):
    __emulates__ = set

    def __init__(self):
        self.data = set()
    def append(self, item):
        self.data.add(item)
    def remove(self, item):
        self.data.remove(item)
    def __iter__(self):
        return iter(self.data)

由于append,这个类看起来像列表一样,但是__emulates__强制它设置。remove是已知的设置界面的一部分,将被检测。

但是这个类还不行:需要一点点粘合剂才能适应SQLAlchemy的使用。ORM需要知道使用哪些方法来追加,删除和迭代集合的成员。当使用像listset这样的类型时,适当的方法是众所周知的,并且在存在时自动使用。这个集合类没有提供预期的add方法,所以我们必须通过装饰器为ORM提供一个明确的映射。

通过装饰器注释自定义集合

装饰器可用于标记ORM管理集合所需的各个方法。当你的类没有完全满足它的容器类型的常规接口,或者你想用其他方法来完成工作时,使用它们。

from sqlalchemy.orm.collections import collection

class SetLike(object):
    __emulates__ = set

    def __init__(self):
        self.data = set()

    @collection.appender
    def append(self, item):
        self.data.add(item)

    def remove(self, item):
        self.data.remove(item)

    def __iter__(self):
        return iter(self.data)

这就是完成这个例子所需要的。SQLAlchemy将通过append方法添加实例。remove__iter__是集合的默认方法,将用于删除和迭代。默认的方法也可以改变:

from sqlalchemy.orm.collections import collection

class MyList(list):
    @collection.remover
    def zark(self, item):
        # do something special...

    @collection.iterator
    def hey_use_this_instead_for_iteration(self):
        # ...

没有要求列表,或根本设置。集合类可以是任何形状,只要它们具有标记为SQLAlchemy使用的append,remove和iterate接口即可。将使用映射实体作为单个参数调用Append和Remove方法,并且不带任何参数调用迭代器方法,并且必须返回一个迭代器。

class sqlalchemy.orm.collections。 collection

实体集合类的装饰器。

装饰者分为两组:注释和截取食谱。

注释装饰器(appender,remover,iterator,linker,converter,inward_instrumented)表示方法的用途,不带任何参数。他们不是写与parens:

@collection.appender
def append(self, append): ...

配方装饰者都需要parens,即使那些没有参数:

@collection.adds('entity')
def insert(self, position, entity): ...

@collection.removes_return()
def popitem(self): ...
静态 tt> 加 tt> arg

将该方法标记为将实体添加到集合中。

向方法添加“添加到集合”处理。decorator参数指示哪个方法参数保存与SQLAlchemy相关的值。参数可以在位置(即整数)或名称中指定:

@collection.adds(1)
def push(self, item): ...

@collection.adds('entity')
def do_stuff(self, thing, entity=None): ...
静态 tt> appender fn

将方法标记为收集appender。

appender方法被调用一个位置参数:要附加的值。如果尚未装饰,方法将自动装饰为“添加(1)”:

@collection.appender
def add(self, append): ...

# or, equivalently
@collection.appender
@collection.adds(1)
def add(self, append): ...

# for mapping type, an 'append' may kick out a previous value
# that occupies that slot.  consider d['a'] = 'foo'- any previous
# value in d['a'] is discarded.
@collection.appender
@collection.replaces(1)
def add(self, entity):
    key = some_key_func(entity)
    previous = None
    if key in self:
        previous = self[key]
    self[key] = entity
    return previous

如果集合中不允许附加值,则可能引发异常。需要记住的是appender将被数据库查询映射的每个对象调用。如果数据库包含违反集合语义的行,则需要具有创意才能解决该问题,因为通过集合进行访问将不起作用。

如果appender方法是内部检测的,则还必须接收关键字参数“_sa_initiator”并确保将其发布到收集事件。

static converter(fn)

将方法标记为收集转换器。

当一个集合被完全替换时,这个可选方法将被调用,如下所示:

myobj.acollection = [newvalue1, newvalue2]

转换器方法将接收被分配的对象,并且应该返回适​​合由appender方法使用的可迭代的值。一个转换器不能赋值或改变集合,它唯一的工作就是将用户提供的值调整为ORM使用的可迭代的值。

默认的转换器实现将使用鸭子键入进行转换。字典集合将被转换成字典值的迭代,而其他类型将被简单地迭代:

@collection.converter
def convert(self, other): ...

如果对象的鸭式键入与此集合的类型不匹配,则会引发TypeError。

如果要扩展可以批量分配的可能类型的范围或对要分配的值执行验证,请提供此方法的实现。

static internally_instrumented(fn)

将该方法标记为已检测。

这个标签将防止任何装饰被应用于该方法。如果您正在使用基本的SQLAlchemy接口方法之一编排您自己对collection_adapter()的调用,或者阻止自动的ABC方法装饰包装您的实现,请使用此方法:

# normally an 'extend' method on a list-like class would be
# automatically intercepted and re-implemented in terms of
# SQLAlchemy events and append().  your implementation will
# never be called, unless:
@collection.internally_instrumented
def extend(self, items): ...
静态 tt> 迭代器 fn

将方法标记为收集卸妆。

迭代器方法被调用没有参数。预计将返回所有集合成员的迭代器:

@collection.iterator
def __iter__(self): ...

deprecated; synonym for collection.linker().

static linker(fn)

将该方法标记为“链接到属性”事件处理程序。

当集合类与InstrumentedAttribute链接或断开连接时,将调用此可选事件处理程序。在实例上设置'_sa_adapter'属性后立即调用它。传递一个参数:链接的集合适配器,或者如果取消链接,则返回None。

自1.0.0版开始弃用: - collection.linker()处理程序被AttributeEvents.init_collection()AttributeEvents.dispose_collection()处理程序。

static remover(fn)

将方法标记为收集卸妆。

使用一个位置参数调用移除方法:要移除的值。如果尚未装饰,该方法将自动用removes_return()进行修饰:

@collection.remover
def zap(self, entity): ...

# or, equivalently
@collection.remover
@collection.removes_return()
def zap(self, ): ...

如果要删除的值在集合中不存在,则可以引发异常或返回无以忽略该错误。

如果remove方法在内部进行检测,则还必须接收关键字参数“_sa_initiator”并确保将其颁发给收集事件。

static removes(arg)

将方法标记为删除集合中的实体。

向方法添加“从集合中删除”处理。decorator参数指示哪个方法参数保存要删除的与SQLAlchemy相关的值。参数可以在位置(即整数)或名称中指定:

@collection.removes(1)
def zap(self, item): ...

对于在调用时不知道要移除的值的方法,请使用collection.removes_return。

static removed_return

将方法标记为删除集合中的实体。

向方法添加“从集合中删除”处理。方法的返回值(如果有的话)被视为要删除的值。方法参数未被检查:

@collection.removes_return()
def pop(self): ...

对于在调用时知道去除的值的方法,使用collection.remove。

静态 tt> 替换 arg

将该方法标记为替换集合中的实体。

向方法添加“添加到集合”和“从集合中删除”处理。装饰器参数指示哪个方法参数保存要添加的SQLAlchemy相关值,以及返回值(如果有)将被视为要删除的值。

参数可以在位置(即整数)或名称中指定:

@collection.replaces(2)
def __setitem__(self, index, item): ...

自定义基于字典的集合

MappedCollection类可以用作自定义类型的基类,也可以作为混合来快速将dict集合支持添加到其他类中。它使用一个键入函数来委托给__setitem____delitem__

from sqlalchemy.util import OrderedDict
from sqlalchemy.orm.collections import MappedCollection

class NodeMap(OrderedDict, MappedCollection):
    """Holds 'Node' objects, keyed by the 'name' attribute with insert order maintained."""

    def __init__(self, *args, **kw):
        MappedCollection.__init__(self, keyfunc=lambda node: node.name)
        OrderedDict.__init__(self, *args, **kw)

When subclassing MappedCollection, user-defined versions of __setitem__() or __delitem__() should be decorated with collection.internally_instrumented(), if they call down to those same methods on MappedCollection. 这是因为MappedCollection上的方法已经被检测到了 - 在一个已经检测到的调用中调用它们可能会导致事件被重复触发或者不恰当地导致内部状态在极少数情况下被破坏:

from sqlalchemy.orm.collections import MappedCollection,\
                                    collection

class MyMappedCollection(MappedCollection):
    """Use @internally_instrumented when your methods
    call down to already-instrumented methods.

    """

    @collection.internally_instrumented
    def __setitem__(self, key, value, _sa_initiator=None):
        # do something with key, value
        super(MyMappedCollection, self).__setitem__(key, value, _sa_initiator)

    @collection.internally_instrumented
    def __delitem__(self, key, _sa_initiator=None):
        # do something with key
        super(MyMappedCollection, self).__delitem__(key, _sa_initiator)

ORM理解dict接口,就像列表和集合一样,如果你选择继承dict或者提供类似dict的集合行为,它将自动处理所有类似于dict的方法鸭子类。您必须修饰appender和remover方法,但是 - 默认情况下,SQLAlchemy的基本字典接口中没有兼容的方法。迭代将通过itervalues(),除非另有修饰。

注意

由于版本0.7.6之前的MappedCollection中存在一个bug,通常需要在使用collection.internally_instrumented()的自定义MappedCollection子类之前调用​​这个解决方法:

from sqlalchemy.orm.collections import _instrument_class, MappedCollection
_instrument_class(MappedCollection)

这将确保MappedCollection在自定义子类中使用之前,已经使用自定义__setitem__()__delitem__()方法正确初始化。

class sqlalchemy.orm.collections.MappedCollection(keyfunc)

Bases: __builtin__.dict

基本的基于字典的集合类。

使用集合类所需的最小包语义扩展字典。setremove是通过键控函数实现的:任何可调用的方法都需要一个对象并返回一个用作字典键的对象。

__初始化__ T0> ( T1> keyfunc T2> ) T3> ¶ T4>

用keyfunc提供的键控创建一个新的集合。

keyfunc可以是任何可调用的对象,并返回一个用作字典键的对象。

每当ORM需要按值添加成员(例如从数据库加载实例时)或删除成员时,keyfunc都会被调用。The usual cautions about dictionary keying apply- keyfunc(object) should return the same output for the life of the collection. 基于可变属性的键控可能会导致集合中的“无法访问”实例“丢失”。

清除 →无。删除D. 中的所有项目
pop tt> k d ] t6>)→v,移除指定的键并返回相应的值。

如果没有找到key,给定返回d,否则引发KeyError

popitem →(k,v),移除并返回一些(key,value)对作为¶ t3 >

2元组;但如果D为空则引发KeyError。

删除 _sa_initiator =无 t5 >

按值删除一个项目,查询关键的keyfunc。

set value_sa_initiator = None t5 >

按值添加项目,查询密钥的keyfunc。

setdefault(k[, d]) → D.get(k,d), also set D[k]=d if k not in D
update([E, ]**F) → None. 从dict / iterable E和F中更新D。

如果E存在且具有.keys()方法,则:对于E中的k:D [k] = E [k]如果E存在并且缺少.keys()方法,则:for(k,v)in E: D [k] = v在任一情况下,这后面是:对于F中的k:D [k] = F [k]

仪表和自定义类型

许多自定义类型和现有库类可以作为实体集合类型使用。但是,需要注意的是,检测过程将会修改类型,自动在方法中添加装饰器。

装饰是轻量级的,除了关系之外没有任何操作,但是在其他地方触发时会增加不必要的开销。当使用库类作为集合时,最好使用“平凡的子类”技巧将装饰限制在关系中使用。例如:

class MyAwesomeList(some.great.library.AwesomeList):
    pass

# ... relationship(..., collection_class=MyAwesomeList)

The ORM uses this approach for built-ins, quietly substituting a trivial subclass when a list, set or dict is used directly.

Collection Internals

各种内部方法。

sqlalchemy.orm.collections.bulk_replace(values, existing_adapter, new_adapter)

加载一个新的集合,根据之前的喜欢的成员资格触发事件。

values中的实例附加到new_adapter上。对于existing_adapter中不存在的任何实例,事件将被触发。values中不存在的existing_adapter中的任何实例都将删除在它们上面触发的事件。

参数:
class sqlalchemy.orm.collections。 集合

实体集合类的装饰器。

装饰者分为两组:注释和截取食谱。

注释装饰器(appender,remover,iterator,linker,converter,inward_instrumented)表示方法的用途,不带任何参数。他们不是写与parens:

@collection.appender
def append(self, append): ...

配方装饰者都需要parens,即使那些没有参数:

@collection.adds('entity')
def insert(self, position, entity): ...

@collection.removes_return()
def popitem(self): ...
sqlalchemy.orm.collections。 collection_adapter =&lt; operator.attrgetter object&gt;

获取集合的CollectionAdapter

class sqlalchemy.orm.collections.CollectionAdapter(attr, owner_state, data)

ORM和任意Python集合之间的桥梁。

代理基本级集合操作(​​追加,删除,迭代)到底层的Python集合,并发出进入或离开集合的实体的添加/删除事件。

ORM仅使用CollectionAdapter来与实体集合进行交互。

class sqlalchemy.orm.collections。 InstrumentedDict

Bases: __builtin__.dict

内置字典的工具版本。

class sqlalchemy.orm.collections。 InstrumentedList

基础:__builtin__.list

内置列表的工具版本。

class sqlalchemy.orm.collections。 InstrumentedSet

基础:__builtin__.set

内置集合的插装版本。

sqlalchemy.orm.collections。 T0> prepare_instrumentation T1> ( T2> 工厂 T3> ) T4>

准备一个可调用的作为集合类工厂的未来使用。

给定一个集合类工厂(无论是可调用的类型还是非可调用的),都返回另一个调用时将生成兼容实例的工厂。

该函数负责将collection_class = list转换为collection_class = InstrumentedList的运行时行为。