排序列表¶
一个自定义列表,用于管理包含元素的索引/位置信息。
作者:
杰森·嘉德兰
OrderingList
是可变有序关系的帮助程序。它将拦截对 relationship()
管理的集合执行的列表作,并自动将列表位置的更改同步到目标标量属性上。
示例:幻灯片
表,其中每行引用相关项目符号
表中的零个或多个条目。幻灯片中的项目符号根据 position
列的值按顺序显示
Bullet
表。 当条目在内存中重新排序时,
position
属性应更新以反映新的排序顺序:
Base = declarative_base()
class Slide(Base):
__tablename__ = "slide"
id = Column(Integer, primary_key=True)
name = Column(String)
bullets = relationship("Bullet", order_by="Bullet.position")
class Bullet(Base):
__tablename__ = "bullet"
id = Column(Integer, primary_key=True)
slide_id = Column(Integer, ForeignKey("slide.id"))
position = Column(Integer)
text = Column(String)
标准关系映射将在每个
包含
所有相关 Bullet
对象的幻灯片,但不会自动处理顺序的变化。将 Bullet
附加到 Slide.bullets
中时,Bullet.position
属性将保持未设置状态,直到手动分配。 当 Bullet
插入到列表的中间,则还需要对以下 Bullet
对象重新编号。
OrderingList
对象自动执行此任务,管理
position
属性。它是使用
ordering_list()
工厂构建的:
from sqlalchemy.ext.orderinglist import ordering_list
Base = declarative_base()
class Slide(Base):
__tablename__ = "slide"
id = Column(Integer, primary_key=True)
name = Column(String)
bullets = relationship(
"Bullet",
order_by="Bullet.position",
collection_class=ordering_list("position"),
)
class Bullet(Base):
__tablename__ = "bullet"
id = Column(Integer, primary_key=True)
slide_id = Column(Integer, ForeignKey("slide.id"))
position = Column(Integer)
text = Column(String)
使用上述映射,可以管理 Bullet.position
属性:
s = Slide()
s.bullets.append(Bullet())
s.bullets.append(Bullet())
s.bullets[1].position
>>> 1
s.bullets.insert(1, Bullet())
s.bullets[2].position
>>> 2
OrderingList
构造仅适用于对集合的更改,而不适用于从数据库进行的初始加载,并且要求在加载时对列表进行排序。因此,order_by
请务必在
relationship()
来验证 TARGET Ordering 属性,以便在首次加载时排序是正确的。
警告
OrderingList
仅在主键列或唯一列是排序的目标时提供有限的功能。不受支持或有问题的作包括:
两个条目必须交易价值。在主键或唯一约束的情况下,不直接支持这样做,因为这意味着在切换发生时,至少需要先暂时删除一行,或者更改为第三个中性值。
必须删除条目才能为新条目腾出空间。SQLAlchemy 的工作单元在一次刷新中执行 DELETE 之前的所有 INSERT。对于主键,它会将同一主键的 INSERT/DELETE 换成 UPDATE 语句,以减少此限制的影响,但对于 UNIQUE 列,则不会发生这种情况。未来的功能将允许“DELETE before INSERT”行为成为可能,从而减轻了这一限制,尽管此功能将需要在映射器级别对要以这种方式处理的列集进行显式配置。
ordering_list()
将相关对象的 ordering 属性的名称作为参数。默认情况下,对象在 ordering_list()
中位置的从零开始的整数索引与 ordering 属性同步:索引 0 将获得位置 0,索引 1 将获得位置 1,依此类推。要从 1 或其他整数开始编号,请提供 count_from=1
。
API 参考¶
对象名称 |
描述 |
---|---|
|
|
|
|
|
|
|
|
|
-
函数 sqlalchemy.ext.orderinglist 中。ordering_list(attr: str, count_from:intNone=None, ordering_func:Callable[[int,Sequence[_T]],int]None=None, reorder_on_append: bool = False)可调用[[], 订购列表] ¶
准备一个OrderingList
工厂以用于 Mapper 定义。
返回一个适合用作 Mapper 关系的collection_class
选项的参数的对象。例如:from sqlalchemy.ext.orderinglist import ordering_list class Slide(Base): __tablename__ = "slide" id = Column(Integer, primary_key=True) name = Column(String) bullets = relationship( "Bullet", order_by="Bullet.position", collection_class=ordering_list("position"), )
参数
其他参数将传递给OrderingList
构造函数。
-
函数 sqlalchemy.ext.orderinglist 中。count_from_0(index, collection)¶
编号功能:从 0 开始的连续整数。
-
函数 sqlalchemy.ext.orderinglist 中。count_from_1(index, collection)¶
编号功能:从 1 开始的连续整数。
-
函数 sqlalchemy.ext.orderinglist 中。count_from_n_factory(start),
编号功能:从任意起点开始的连续整数。
-
类 sqlalchemy.ext.orderinglist 中。排序列表¶
一个自定义列表,用于管理其子项的位置信息。OrderingList
对象通常使用ordering_list()
工厂函数,与relationship()
函数结合使用。
类签名
classsqlalchemy.ext.orderinglist.OrderingList
(builtins.list
,typing.通用
)-
方法sqlalchemy.ext.orderinglist.OrderingList.
__init__(ordering_attr:strNone=None, ordering_func:Callable[[int,Sequence[_T]],int]None=None, reorder_on_append: bool = False)¶
一个自定义列表,用于管理其子项的位置信息。OrderingList
是一个collection_class
列表实现,它将 Python 列表中的 position 与 Map 对象上的 position 属性同步。
此实现依赖于以正确的顺序开始的列表,因此请务必对你的关系进行order_by
。
参数
ordering_attr¶– 在关系中存储对象顺序的属性的名称。ordering_func¶ –
自选。 一个函数,该函数将 将 Python 列表转换为要存储在ordering_attr
。返回的值通常是(但不一定是)整数。
使用两个位置参数调用ordering_func
:列表中元素的索引和列表本身。
如果省略,则 Python 列表索引将用于属性值。 本模块提供了两个基本的预构建编号功能:count_from_0
和count_from_1
。有关更多奇特的示例,如阶梯编号、字母顺序和斐波那契编号,请参阅单元测试。reorder_on_append¶ –
默认为 False。 当附加具有现有 (non-None) 的对象时 ordering 值,该值将保持不变,除非reorder_on_append
是真的。这是一种优化,可避免各种危险的意外数据库写入。
SQLAlchemy 将在对象加载时通过 append() 将实例添加到列表中。如果由于某种原因,数据库中的结果集跳过了排序中的一个步骤(例如,缺少行 '1',但您得到了 '2'、'3' 和 '4'),reorder_on_append=True 会立即将项目重新编号为 '1'、'2'、'3'。如果你有多个会话进行更改,其中任何一个会话碰巧加载了这个集合,即使顺便加载了这个集合,所有会话都会尝试 “清理” 其提交中的编号,这可能会导致除一个会话之外的所有会话都失败并出现并发修改错误。
建议将其保留为默认值 False,然后调用reorder()
如果你正在对以前排序的实例进行append()
作,或者在手动 SQL作后进行一些内务处理。
-
方法sqlalchemy.ext.orderinglist.OrderingList.
append(entity)¶
将 object 附加到列表的末尾。
-
方法sqlalchemy.ext.orderinglist.OrderingList.
insert(index, entity)¶
在索引之前插入对象。
-
方法sqlalchemy.ext.orderinglist.OrderingList.
pop(index=-1)¶
删除并返回 index 处的项目(默认为 last)。
如果 list 为空或 index 超出范围,则引发 IndexError 。
-
方法sqlalchemy.ext.orderinglist.OrderingList.
remove(entity)¶
删除第一个出现的值。
如果值不存在,则引发 ValueError。
-
方法sqlalchemy.ext.orderinglist.OrderingList.
reorder()无 ¶
同步整个集合的排序。
扫描列表并确保每个对象都设置了准确的排序信息。
-