Release: 1.4.25 | Release Date: September 22, 2021

SQLAlchemy 1.4 Documentation

收集配置和技术

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

处理大型集合

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

动态关系加载器

注解

这是一项传统功能。使用 with_parent() 过滤与联合 select() 是不是 2.0 style 使用方法。对于不应加载的关系,请设置 relationship.lazynoload

注解

此加载程序在一般情况下与 异步I/O(异步) 分机。它的使用有一些限制,如中所示 Asyncio dynamic guidelines

A relationship() 可以配置对应于大型集合的 Query 对象,这允许根据条件筛选关系。这个班级是一个特殊的班级。 AppenderQuery 在访问时代替集合返回。可以显式或通过数组切片应用过滤标准以及限制和偏移量:

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]

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

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

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

由于动态关系的读取端总是查询数据库,因此在刷新数据之前,对基础集合的更改将不可见。但是,只要在 Session 在使用中,每次集合即将发出查询时,都会自动发生这种情况。

要在backref上放置动态关系,请使用 backref() 功能与 lazy='dynamic' ::

class Post(Base):
    __table__ = posts_table

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

请注意,此时不能将热切/懒惰加载选项与动态关系结合使用。

Object Name Description

AppenderQuery

支持基本集合存储操作的动态查询。

class sqlalchemy.orm.AppenderQuery(attr, state)

支持基本集合存储操作的动态查询。

类签名

class sqlalchemy.orm.AppenderQuery (sqlalchemy.orm.dynamic.AppenderMixin, sqlalchemy.orm.Query)

注解

这个 dynamic_loader() 功能与 relationship()lazy='dynamic' 指定了参数。

警告

“动态”装载机适用于 仅收集 . 使用多对一、一对一或useList=false关系的“动态”加载程序是无效的。在这些情况下,新版本的SQLAlchemy会发出警告或异常。

设置无负载,raiseload

“noload”关系从不从数据库加载,即使在访问时也是如此。它是使用 lazy='noload' ::

class MyClass(Base):
    __tablename__ = 'some_table'

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

上面, children 集合是完全可写的,对它所做的更改将被持久化到数据库中,并且在添加时本地可供读取。但是,当 MyClass 是从数据库中新加载的, children 集合保持为空。noload策略也可以在查询选项的基础上使用 noload() 装入程序选项。

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

class MyClass(Base):
    __tablename__ = 'some_table'

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

上面,属性访问 children 如果集合之前未被预先加载,则将引发异常。这包括读取访问,但对于集合,也会影响写入访问,因为如果不首先加载集合,就无法对其进行更改。其基本原理是确保应用程序不会在特定上下文中发出任何意外的延迟负载。“提升”策略不必通过读取SQL日志来确定所有必要的属性都是预先加载的,“提升”策略将导致卸载的属性在被访问时立即提升。在查询选项的基础上,还可以使用 raiseload() 装入程序选项。

1.1 新版功能: 增加了“提升”装载机策略。

使用被动删除

在具有ORM关系的DELETE cascade中使用外键 对于这个部分。

自定义集合访问

将一对多或多对多关系映射会导致通过父实例上的属性可访问的值集合。默认情况下,此集合是 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 选择权 relationship() ::

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 键入到的项 Note.keyword 属性:

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 是一本字典:

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

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

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

属性 attribute_mapped_collection() 用作密钥根本不需要映射!使用常规的python @property 允许将对象的任何细节或细节组合用作键,如下所示,当我们将其建立为 Note.keyword 前十个字母 Note.text 领域:

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 后盾。分配给这个反向关系, Note 被添加到 Item.notes 字典和密钥自动为我们生成:

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

其他内置字典类型包括 column_mapped_collection() 就像是 attribute_mapped_collection() 除非给出 Column 直接对象:

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

字典映射通常与“关联代理”扩展结合使用,以生成简化的字典视图。见 代理到基于字典的集合复合关联代理 举个例子。

处理关键突变和字典集合的回填充

使用时 attribute_mapped_collection() ,字典的“键”取自目标对象的属性。 不跟踪对该键的更改 . 这意味着密钥必须在第一次使用时分配给,如果密钥更改,则集合将不会发生变化。当依赖backrefs填充属性映射集合时,这可能是一个典型的问题。考虑到以下因素:

class A(Base):
    __tablename__ = "a"

    id = Column(Integer, primary_key=True)
    bs = relationship(
        "B",
        collection_class=attribute_mapped_collection("data"),
        back_populates="a",
    )


class B(Base):
    __tablename__ = "b"
    id = Column(Integer, primary_key=True)
    a_id = Column(ForeignKey("a.id"))
    data = Column(String)

    a = relationship("A", back_populates="bs")

如果我们创建一个 B() 指的是 A() ,后面的填充将添加 B()A.bs 但是,如果 B.data 尚未设置,关键在于 None ::

>>> a1 = A()
>>> b1 = B(a=a1)
>>> a1.bs
{None: <test3.B object at 0x7f7b1023ef70>}

设置 b1.data 事后不更新集合:

>>> b1.data = 'the key'
>>> a1.bs
{None: <test3.B object at 0x7f7b1023ef70>}

如果一个人试图建立 B() 在构造函数中。参数的顺序会改变结果:

>>> B(a=a1, data='the key')
<test3.B object at 0x7f7b10114280>
>>> a1.bs
{None: <test3.B object at 0x7f7b10114280>}

vs::

>>> B(data='the key', a=a1)
<test3.B object at 0x7f7b10114340>
>>> a1.bs
{'the key': <test3.B object at 0x7f7b10114340>}

如果以这种方式使用backref,请确保使用 __init__ 方法。

以下事件处理程序也可用于跟踪集合中的更改:

from sqlalchemy import event

from sqlalchemy.orm import attributes

@event.listens_for(B.data, "set")
def set_item(obj, value, previous, initiator):
    if obj.a is not None:
        previous = None if previous == attributes.NO_VALUE else previous
        obj.a.bs[value] = obj
        obj.a.bs.pop(previous)
Object Name Description

attribute_mapped_collection(attr_name)

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

column_mapped_collection(mapping_spec)

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

mapped_collection(keyfunc)

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

function sqlalchemy.orm.collections.attribute_mapped_collection(attr_name)

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

返回A MappedCollection 带有基于集合中实体的“attr_name”属性的键控的工厂,其中 attr_name 属性的字符串名称。

警告

键值必须指定给其最终值 之前 它由属性映射集合访问。此外,对key属性的更改包括 未跟踪 自动,这意味着字典中的键不会自动与目标对象本身的键值同步。参见章节 处理关键突变和字典集合的回填充 举个例子。

function sqlalchemy.orm.collections.column_mapped_collection(mapping_spec)

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

返回A MappedCollection 一个工厂,其中有一个键控函数,该键控函数由mapping_spec生成,它可以是列或列序列。

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

function sqlalchemy.orm.collections.mapped_collection(keyfunc)

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

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

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

自定义集合实现

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

我需要自定义集合实现吗?

在大多数情况下根本不是!“自定义”集合最常见的用例是将传入值验证或封送到新表单中的用例,例如成为类实例的字符串,或者以某种方式超越并表示内部数据的用例,在不同表单的外部显示该数据的“视图”。

对于第一个用例, validates() 在所有情况下,为了验证和简单的封送,decorator是截取传入值的最简单方法。见 简单验证器 举个例子。

对于第二个用例, 关联代理 扩展是一个测试良好、广泛使用的系统,它根据目标对象上的某些属性提供集合的读/写“视图”。因为目标属性可以是 @property 它实际上返回任何内容,集合的大量“可选”视图可以用几个函数构造。这种方法使底层的映射集合不受影响,并且避免了需要在一个方法一个方法的基础上仔细地调整集合行为。

当集合需要在访问或突变操作时具有特殊的行为,而这些操作不能在集合外部建模时,定制的集合非常有用。当然,它们可以与上述两种方法相结合。

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

collections包了解列表、集合和dict的基本接口,并将自动将instruction应用于这些内置类型及其子类。通过duck类型检测和检测实现基本集合接口的对象派生类型:

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__ 不是mutator方法,不会被检测,并且 foo 也不会。

当然,duck类型(即猜测)并不可靠,因此您可以通过提供 __emulates__ 类属性:

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提供显式映射。

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

decorator可用于标记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方法,并且不使用参数调用迭代器方法,并且必须返回迭代器。

Object Name Description

collection

实体集合类的修饰符。

class sqlalchemy.orm.collections.collection

实体集合类的修饰符。

装饰师分为两组:注释和拦截配方。

注释修饰符(appender、remover、iterator、converter、internal-instrumented)指示方法的用途,不带参数。它们不是用帕伦斯写的:

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

配方装饰师都需要帕伦斯,甚至那些不带参数的:

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

@collection.removes_return()
def popitem(self): ...
method sqlalchemy.orm.collections.collection.static adds(arg)

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

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

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

@collection.adds('entity')
def do_stuff(self, thing, entity=None): ...
method sqlalchemy.orm.collections.collection.static appender(fn)

将方法标记为集合附加器。

使用一个位置参数调用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方法进行了检测,则还必须接收关键字参数“_sa_initiator”,并确保将其发布到集合事件。

method sqlalchemy.orm.collections.collection.static converter(fn)

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

1.3 版后已移除: 这个 collection.converter() 处理程序已弃用,将在将来的版本中删除。请参阅 bulk_replace 侦听器接口与 listen() 功能。

当完全替换集合时,将调用此可选方法,如::

myobj.acollection = [newvalue1, newvalue2]

Converter方法将接收被分配的对象,并应返回适合于 appender 方法。转换器不能赋值或改变集合,它的唯一任务是将用户提供的值调整为可供ORM使用的值。

默认的转换器实现将使用duck类型进行转换。类似dict的集合将转换为字典值的iterable,其他类型将简单地迭代:

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

如果对象的duck类型与此集合的类型不匹配,则会引发类型错误。

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

method sqlalchemy.orm.collections.collection.static internally_instrumented(fn)

将方法标记为已检测。

此标记将阻止对该方法应用任何装饰。如果您正在安排自己的呼叫 collection_adapter() 在一个基本的sqlAlchemy接口方法中,或者为了防止自动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): ...
method sqlalchemy.orm.collections.collection.static iterator(fn)

将该方法标记为集合移除器。

调用迭代器方法时没有参数。它应返回所有集合成员的迭代器::

@collection.iterator
def __iter__(self): ...
method sqlalchemy.orm.collections.collection.static remover(fn)

将该方法标记为集合移除器。

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

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

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

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

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

method sqlalchemy.orm.collections.collection.static removes(arg)

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

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

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

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

method sqlalchemy.orm.collections.collection.static removes_return()

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

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

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

对于调用时已知要移除的值的方法,请使用collection.remove。

method sqlalchemy.orm.collections.collection.static replaces(arg)

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

将“添加到集合”和“从集合中移除”处理添加到方法。decorator参数指示哪个方法参数保存要添加的与sqlachemy相关的值,如果有的话,返回值将被视为要移除的值。

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

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

子类化时 MappedCollection ,的用户定义版本 __setitem__()__delitem__() 应该用 collection.internally_instrumented()if 它们调用相同的方法 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 或者在duck类型的类中提供类似dict的收集行为。但是,您必须修饰appender和remover方法,因为在基本字典接口中没有可供SQLAlchemy默认使用的兼容方法。迭代将经历 itervalues() 除非另有装饰。

注解

由于0.7.6版之前的mappedCollection中存在错误,通常需要在自定义子类 MappedCollection 其中使用 collection.internally_instrumented() 可用于:

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

这将确保 MappedCollection 已用自定义正确初始化 __setitem__()__delitem__() 方法。

Object Name Description

MappedCollection

基于字典的基本集合类。

class sqlalchemy.orm.collections.MappedCollection(keyfunc)

基于字典的基本集合类。

使用集合类所需的最小包语义扩展dict。 setremove 以键控函数的形式实现:任何接受对象并返回用作字典键的对象的可调用函数。

类签名

class sqlalchemy.orm.collections.MappedCollection (builtins.dict)

method sqlalchemy.orm.collections.MappedCollection.__init__(keyfunc)

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

keyfunc可以是接受对象并返回用作字典键的对象的任何可调用项。

每次ORM只需要按值添加成员(例如从数据库加载实例时)或删除成员时,都将调用keypunc。字典键控的常见注意事项- keyfunc(object) 应在集合的生命周期内返回相同的输出。基于可变属性的键控可能会导致集合中无法访问的实例“丢失”。

method sqlalchemy.orm.collections.MappedCollection.clear() None.  Remove all items from D.
method sqlalchemy.orm.collections.MappedCollection.pop(k[, d]) v, remove specified key and return the corresponding value.

如果找不到键,则返回d(如果给定),否则将引发keyError

method sqlalchemy.orm.collections.MappedCollection.popitem() (k, v), remove and return some (key, value) pair as a

2元组;但如果d为空,则引发keyror。

method sqlalchemy.orm.collections.MappedCollection.remove(value, _sa_initiator=None)

按值删除一个项目,请咨询密钥的keyfunc。

method sqlalchemy.orm.collections.MappedCollection.set(value, _sa_initiator=None)

按值添加一个项目,并为该键咨询keyfunc。

method sqlalchemy.orm.collections.MappedCollection.setdefault(key, default=None)

如果关键字不在字典中,则插入值为默认值的关键字。

如果键在字典中,则返回键的值,否则为默认值。

method sqlalchemy.orm.collections.MappedCollection.update([E, ]**F) None.  Update D from dict/iterable E and F.

如果e存在并且有.keys()方法,那么对e:d中的k执行:操作 [k] = e [k] 如果e存在,并且缺少.keys()方法,则为:对于k,e:d中的v [k] =v在任何一种情况下,后面跟着:对于f:d中的k [k] = f [k]

仪表和自定义类型

许多自定义类型和现有库类可以用作实体集合类型,而无需进一步的ADO。但是,需要注意的是,检测过程将修改类型,并自动在方法周围添加修饰符。

装饰是轻量级的,在关系之外没有任何操作,但在其他地方触发时,它们确实增加了不必要的开销。当使用库类作为集合时,使用“琐碎的子类”技巧将修饰限制为仅在关系中使用是一种很好的做法。例如:

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

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

ORM将此方法用于内置项,当 listsetdict 直接使用。

收集内部

各种内部方法。

Object Name Description

bulk_replace(values, existing_adapter, new_adapter[, initiator])

加载一个新的集合,根据以前类似的成员身份触发事件。

collection

实体集合类的修饰符。

collection_adapter

拿来 CollectionAdapter 收藏。

CollectionAdapter

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

InstrumentedDict

内置dict的检测版本。

InstrumentedList

内置列表的检测版本。

InstrumentedSet

内置集的检测版本。

prepare_instrumentation(factory)

准备一个可调用文件,以备将来用作集合类工厂。

function sqlalchemy.orm.collections.bulk_replace(values, existing_adapter, new_adapter, initiator=None)

加载一个新的集合,根据以前类似的成员身份触发事件。

在中附加实例 valuesnew_adapter . 将为不在中的任何实例激发事件 existing_adapter . 中的任何实例 existing_adapter 不存在于 values 将删除对其激发的事件。

参数
class sqlalchemy.orm.collections.collection

实体集合类的修饰符。

装饰师分为两组:注释和拦截配方。

注释修饰符(appender、remover、iterator、converter、internal-instrumented)指示方法的用途,不带参数。它们不是用帕伦斯写的:

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

配方装饰师都需要帕伦斯,甚至那些不带参数的:

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

@collection.removes_return()
def popitem(self): ...
sqlalchemy.orm.collections.collection_adapter = operator.attrgetter('_sa_adapter')

拿来 CollectionAdapter 收藏。

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

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

将基本级别的集合操作(append、remove、iterate)代理到基础python集合,并为进入或离开集合的实体发出添加/删除事件。

ORM使用 CollectionAdapter 仅用于与实体集合的交互。

class sqlalchemy.orm.collections.InstrumentedDict

内置dict的检测版本。

类签名

class sqlalchemy.orm.collections.InstrumentedDict (builtins.dict)

class sqlalchemy.orm.collections.InstrumentedList(iterable=(), /)

内置列表的检测版本。

类签名

class sqlalchemy.orm.collections.InstrumentedList (builtins.list)

class sqlalchemy.orm.collections.InstrumentedSet

内置集的检测版本。

类签名

class sqlalchemy.orm.collections.InstrumentedSet (builtins.set)

function sqlalchemy.orm.collections.prepare_instrumentation(factory)

准备一个可调用文件,以备将来用作集合类工厂。

给定一个集合类工厂(类型或无arg可调用),返回另一个工厂,该工厂在调用时将生成兼容的实例。

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

Previous: 配置关系联接方式 Next: 特殊关系持续模式