2013-01-23 25 views
4

我從表中刪除此行,它還包含了許多對FKS級聯,最終它給了我這個錯誤:在Postgresql中,如何調試刪除級聯後發生的錯誤?

ERROR: insert or update on table "foo_route" violates foreign key constraint "foo_route_bar_fk"

SQL state: 23503

Detail: Key (bar_key)=(2176) is not present in table "bar".

foo_route_bar_fk的定義是這樣的:

ALTER TABLE foo_route 
ADD CONSTRAINT foo_route_bar_fk FOREIGN KEY (bar_key) REFERENCES bar (bar_key) 
MATCH SIMPLE ON UPDATE NO ACTION ON DELETE CASCADE; 

我通過刪除與這兩個表無關的表來得到這個錯誤。我認爲發生的事情是觸發器或級聯引起的這個錯誤,但很難找出原因。

我的問題是,你如何在postgresql中調試像這樣的問題? 導致此錯誤的一系列步驟是什麼? Postgresql只告訴我它在失敗之前做的最後一件事的結果。如果這是代碼,那麼錯誤會提供非常有用的堆棧跟蹤。有沒有辦法在Postgresql中看到類似的東西?

+1

您應該在服務器日誌中找到更多詳細信息。我懷疑你上面顯示的是你的客戶打印的錯誤信息。 –

+0

@PeterEisentraut是的,這是正確的,它來自客戶端。我會看看server.log。有沒有有用的日誌記錄默認關閉? –

+0

與此相關的內容應默認打開。但很多其他有用的東西不是。 –

回答

2

通常你的postgresql日誌將包含觸發錯誤的語句。這應該可以讓你跟隨連鎖事件。

然而,我會建議的一件事情是,你可能想繪製一張fkeys的地圖,並查看外鍵上ON事件的映射。如果是我,我會從模式轉儲或pg_autodoc輸出開始,然後從那裏開始。顯而易見的問題是,如果您無法在這裏查看並重新考慮問題,則會刪除級聯。

+0

*「顯而易見的問題是,如果不能解釋,你就刪除了級聯」 - 解釋?我不知道有任何情況會導致嘗試級聯「DELETE」失敗,除此之外還會違反其他約束條件。但是,這似乎並不是這種情況,因爲如果是這樣,我們期望在錯誤消息中看到其他約束,並且因爲出現在這裏的錯誤消息只能由'INSERT'或影響*引用*列的'UPDATE',而不是*引用*處的'UPDATE'或'DELETE'。 –

+0

好的,從你的問題描述中發生的事情是:刪除一個級聯刪除B,失敗,因爲行C仍然引用它。 (這是級聯刪除IMO很少有用的原因之一,因爲它們將這種複雜性添加到應用程序中)。 –

+0

但是我們知道這是*不是發生了什麼*這裏,因爲我剛剛給的原因。我們從錯誤消息中知道,*引用*列上的'INSERT'或'UPDATE'是觸發它的東西,我們也知道,如果它*是從觸發它的引用列中刪除的,它應該級聯,沒有錯誤。另外:在你描述的場景中,只要從C指向B的鍵被設置爲「ON DELETE CASCADE」,一切都會級聯。你所描述的問題只是在約束鏈中有一些約束設置爲級聯而另一些不約束。 –