亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

交換唯一值時如何在唯一性約束上避免 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 關注
  • 93 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號