2011-08-02 35 views
3

鑑於Django模型:爲什麼現實世界中的Django模型級聯刪除失敗?

 

class ContainerOwner(models.Model): 
    id = models.IntegerField() 

class Container(models.Model): 
    owner = models.ForeignKey(ContainerOwner) 

如果您在「ContainerOwner」調用.delete()反對將級聯刪除所有由「ContainerOwner」所擁有的「容器」的對象。

但我發現在我的真實生活django項目中,有些時候級聯刪除似乎失敗了。它似乎偶爾發生,當系統處於高容量時。因此,在「ContainerOwner」已被刪除後(這應該是不可能的,Container會始終有一個'ContainerOwner'),最終會出現沒有有效的「ContainerOwner」的「Container」對象。)

有沒有人看過這種類型之前的失敗,並可以解釋它是如何發生的?應用程序或數據庫服務器進行級聯刪除的過程中,級聯刪除是否可以半途殺死?


更新問題,根據答案反饋:

1)我們正在使用的MyISAM與MySQL

2)我們正在使用的查詢集刪就刪 「ContainerOwner」 對象的查詢集

3)MySQL後端

4)我們有一個非常共同行動,其中包含3個的「Django的查詢集nerOwner「對象一次全部刪除,並且所有」容器「對象也應該刪除。這種情況每天發生幾十次,我們只是注意到存在導致應用程序錯誤的這些孤立的「容器」對象。看起來只有非常小的百分比的刪除失敗,例如0.01%的刪除導致有一些孤兒。

回答

2

這不是真的有可能來回答您的實際問題,不知道很多詳細瞭解您的應用程序,如:

  1. 你有ContainerOwner.delete()Container.delete()任何自定義邏輯?
  2. 您是否在ContainerOwner的任何位置使用queryset的delete
  3. 你正在使用什麼數據庫?
  4. 創建/更新的一般使用模式/刪除ContainerOwner/Container對象

但最重要的是:

"Container" objects that have no valid "ContainerOwner" after the "ContainerOwner" has been deleted

擺在首位的數據庫級別,這不應成爲可能,除非你缺少外鍵約束,或者你正在使用不支持FK約束的數據庫(如MySQL + MYISAM)。如果是前者,你應該先解決。如果是後者,請考慮切換,具體取決於您的應用的實際重要性。

+0

感謝您對指導性問題的幫助,我用底部的答案更新了原始問題。 – MikeN

0

如果其他人在此期間添加了一個容器,它具有相同的ContainerOwner,並且您在事務之外,它將無法刪除。在這種情況下你應該得到一個IntegrityError。另外,如果您有任何超出django的代碼,並且存在其他衝突的數據庫約束,那麼這些將防止級聯刪除。

嘗試檢查您的數據庫日誌,並查看刪除失敗的原因。