为了账号安全,请及时绑定邮箱和手机立即绑定

交换唯一值时如何在唯一性约束上避免 SQLAlchemy IntegrityError

交换唯一值时如何在唯一性约束上避免 SQLAlchemy IntegrityError

沧海一幻觉 2023-03-01 16:30:55
我有如下的 SQLAlchemy 模型(从实际实现中抽象出来)class Parent():    id = Column(postgresql.UUID, primary_key=True)class Child():    id = Column(postgresql.UUID, primary_key=True)    parent_id = (postgresql.UUID,sqlalchemy.ForeignKey(Parent.id), nullable=False, index=True)    order = sa_schema.Column(postgresql.SMALLINT)而且我对 parent_id 和 order 有唯一性约束,所以孩子在父母身上的顺序是唯一的。我想编写代码以允许对这些子项进行重新排序,例如,如果我有子项 ABCDE,并且想将子项 B 的顺序从 2 更改为 4,我将 C 从 3 更改为 2,将 D 从 4 更改为 3 . 所有这一切都有效,但是当我提交事务时,我收到一个 IntegrityError ,指出其中一个 order/parent_id 对已经存在(每次都是随机的)。我已经关闭了自动冲洗功能,有人知道我该怎么做吗?示例代码(显然这只处理订单增加的情况):    children_to_update = session.query(models.Child).filter(        models.Child.parent_id == parent_id,        models.Child.order <= new_order,        models.Child.order > original_order,    ).with_for_update(nowait=True).all()    for child_to_update in children_to_update:        child_to_update.order = child_to_update.order - 1        session.add(child_to_update)    original_child.order = new_order    session.add(original_child)    session.commit()
查看完整描述

1 回答

?
湖上湖

TA贡献2003条经验 获得超2个赞

为了使这项工作有效,您首先需要对 deferrable 进行唯一约束(parent_id, order)

然后,您需要通过发送来延迟查询之前的约束set constraints <constraint name|all> deferred;

延迟约束将在 上自动检查commit


查看完整回答
反对 回复 2023-03-01
  • 1 回答
  • 0 关注
  • 74 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信