[英]Flask SQLAlchemy IntegrityError “UNIQUE constraint failed” when trying to update values
[英]How to avoid SQLAlchemy IntegrityError on uniqueness constraint when swapping unique values
我有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 有唯一性约束,因此父级上子级的排序是唯一的。 我想编写代码以允许对这些孩子进行重新排序,例如,如果我有孩子 AB C DE 并希望将孩子 B 的顺序从 2 更改为 4,我将 C 从 3 更改为 2,将 D 从 4到 3。所有这些都正常工作,但是当我 go 提交事务时,我收到一个 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()
要完成这项工作,您首先需要使您对(parent_id, order)
的唯一约束可延迟。
然后,您需要在查询之前通过发送set constraints <constraint name|all> deferred;
来推迟约束。
延迟约束将在commit
时自动检查。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.