最近我發現Django ORM的Model.save()
默認情況下執行SQL來更新'ALL'列,即使沒有任何修改。 這真的讓我擔心,因爲我所做的任何更改都有機會通過其他Model.save()
進程恢復到原始值。Django的Model.save()修改不需要的列
例如,我有一個型號Order
。有兩個併發進程(P1,P2)在其上運行。首先,P1選擇行:
# P1
order = Order.objects.get(pk=10000)
然後,P2選擇同一行,並更新status
列:(下面的語句可以被包裝在一個事務,甚至是SERIALIZABLE之一,但這不能。解決這一問題)
# P2
order = Order.objects.get(pk=10000)
if order.status == UNPAID:
order.status = PAID # update the `status` column
order.save()
之後,P1一些更新等瑣碎柱:
# P1
order.xxx = xxx # update some other trivial column
order.save() # This would set the `status` back to UNPAID !!!
order.status
將被重新設置爲UNPAID
,那不是我想要的。
我知道我可以使用save(update_fields=...)
,select_for_update()
,filter(...).update(...)
,SERIALIZABLE事務,或顯式鎖定P1以防止此問題。 但問題是:在整個項目的所有Model.save()
報表中使用它們是很荒謬的。此外,即使我在我的項目代碼中執行,還有一些其他代碼正在執行此操作(Django Admin,ModelForm ...)。
我應該重寫Model.save()
以只更新那些修改過的字段嗎?
(這似乎是一個嚴重的問題,對我來說,還是我採取了什麼了嗎?)
它發生是因爲'P1'不知道你改變了'P2'的'status'屬性。爲什麼你需要2個不同的引用到相同的'訂單'? – DeepSpace
@DeepSpace我想'P1'和'P2'是不同的過程。 – thebjorn
@DeepSpace是的,它們是不同的過程。例如,工作人員正在使用Django Admin來修改該訂單('P1'),並且客戶正在進行付款('P2')。 – prajnamort