目录

排序表

优质
小牛编辑
130浏览
2023-12-01

管理所包含元素的索引/位置信息的自定义列表。

作者

杰森·科特兰

orderinglist 是可变顺序关系的助手。它将截获在 relationship() -托管集合,并自动将列表位置的更改同步到目标标量属性。

例子:A slide 表,其中每行引用相关的 bullet 表。幻灯片中的项目符号根据 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)

标准关系映射将在每个 Slide 包含所有相关 Bullet 对象,但处理顺序更改不会自动处理。当附加一个 Bullet 进入之内 Slide.bullets , the Bullet.position 在手动分配之前,属性将保持未设置状态。当 Bullet 插入到列表中间,如下所示 Bullet 对象也需要重新编号。

这个 OrderingList 对象自动执行此任务,管理 position 所有属性 Bullet 集合中的对象。它是用 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_byrelationship() 针对目标排序属性,以便在首次加载时正确排序。

警告

OrderingList 仅当主键列或唯一列是排序目标时,才提供有限的功能。不支持或有问题的操作包括:

  • 两个条目必须交换值。在主键或唯一约束的情况下不直接支持这一点,因为这意味着在切换发生时,至少需要先临时删除一行,或将其更改为第三个中性值。

  • 必须删除条目才能为新条目腾出空间。SQLAlchemy的工作单元在一次刷新中删除之前执行所有插入。在主键的情况下,它将同一个主键的插入/删除交易到更新语句中,以减少此限制的影响,但是对于唯一列,这不会发生。未来的功能将允许“插入前删除”行为,从而减轻此限制,尽管此功能将需要在映射器级别为以这种方式处理的列集进行显式配置。

ordering_list() 将相关对象的排序属性的名称作为参数。默认情况下,对象在 ordering_list() 与排序属性同步:索引0将获取位置0、索引1位置1等。若要从1或其他整数开始编号,请提供 count_from=1 .

API引用

Object NameDescription

count_from_0(index, collection)

编号函数:从0开始的连续整数。

count_from_1(index, collection)

编号函数:从1开始的连续整数。

count_from_n_factory(start)

编号函数:从任意开始的连续整数。

ordering_list(attr[, count_from], **kw)

准备一个 OrderingList 用于映射器定义的工厂。

OrderingList

管理其子项位置信息的自定义列表。

function sqlalchemy.ext.orderinglist.ordering_list(attr, count_from=None, **kw)

准备一个 OrderingList 用于映射器定义的工厂。

返回一个适合用作映射器关系参数的对象 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'))
参数
  • attr -- 用于存储和检索排序信息的映射属性的名称

  • count_from -- 设置基于整数的排序,从开始 count_from . 例如, ordering_list('pos', count_from=1) 将在SQL中创建基于1的列表,并将值存储在“pos”列中。忽略如果 ordering_func 供应。

其他参数传递给 OrderingList 建造师。

function sqlalchemy.ext.orderinglist.count_from_0(index, collection)

编号函数:从0开始的连续整数。

function sqlalchemy.ext.orderinglist.count_from_1(index, collection)

编号函数:从1开始的连续整数。

function sqlalchemy.ext.orderinglist.count_from_n_factory(start)

编号函数:从任意开始的连续整数。

class sqlalchemy.ext.orderinglist.OrderingList(ordering_attr=None, ordering_func=None, reorder_on_append=False)

管理其子项位置信息的自定义列表。

这个 OrderingList 对象通常使用 ordering_list() 工厂功能,与 relationship() 功能。

类签名

class sqlalchemy.ext.orderinglist.OrderingList (builtins.list)

method sqlalchemy.ext.orderinglist.OrderingList.__init__(ordering_attr=None, ordering_func=None, reorder_on_append=False)

管理其子项位置信息的自定义列表。

OrderingList 是一个 collection_class 将python列表中的位置与映射对象上的position属性同步的列表实现。

这个实现依赖于以正确顺序开始的列表,所以 sure 放一个 order_by 关于你的关系。

参数
  • ordering_attr -- 在关系中存储对象顺序的属性的名称。

  • ordering_func -- 可选的。将python列表中的位置映射到要存储在 ordering_attr . 返回的值通常是(但不必是!)整数。安 ordering_func 使用两个位置参数调用:列表中元素的索引和列表本身。如果省略,则属性值使用python列表索引。本模块提供了两个基本的预建编号功能: count_from_0count_from_1 . 有关更奇特的例子,如阶梯式编号、字母和斐波那契编号,请参见单元测试。

  • reorder_on_append -- 默认为false。当使用现有(非无)排序值附加对象时,该值将保持不变,除非 reorder_on_append 是真的。这是一种优化,可以避免各种危险的意外数据库写入。当加载对象时,sqlAlchemy将通过append()向列表中添加实例。如果由于某种原因,数据库中的结果集跳过了排序中的一个步骤(例如,缺少行“1”,但您得到了“2”、“3”和“4”),则在“append=true”上重新排序将立即将项重新编号为“1”、“2”、“3”。如果您有多个会话正在进行更改,而其中任何一个会话甚至在传递过程中也恰好加载了此集合,那么所有会话都将尝试“清除”其提交中的编号,这可能会导致除一个会话以外的所有会话都失败,并出现并发修改错误。建议将此项保留为默认值false,然后只需调用 reorder() 如果你正在做 append() 具有以前排序的实例的操作,或者在手动SQL操作之后执行一些内务管理时执行的操作。

method sqlalchemy.ext.orderinglist.OrderingList.append(entity)

将对象追加到列表末尾。

method sqlalchemy.ext.orderinglist.OrderingList.insert(index, entity)

在索引前插入对象。

method sqlalchemy.ext.orderinglist.OrderingList.pop(index=- 1)

移除并返回索引处的项(默认最后一个)。

如果列表为空或索引超出范围,则引发IndexError。

method sqlalchemy.ext.orderinglist.OrderingList.remove(entity)

删除第一次出现的值。

如果值不存在,则引发ValueError。

method sqlalchemy.ext.orderinglist.OrderingList.reorder()

同步整个集合的排序。

扫描列表并确保每个对象都有准确的排序信息集。