2012-10-15 31 views
0

我有一個任務,爲不同表中的一批條目實現「回滾」(不是通常的回滾)功能。例如:Postgres:如何刪除多個表中的條目

def rollback(cursor, entries): 
    # entries is a dict of such form: 
    # {'table_name1': [id1, id2, ...], 'table_name2': [id1, id2, ...], ...} 

我需要刪除每個table_name中的條目。但是因爲這些條目可能有這麼複雜的關係。我的想法分幾個步驟:

  1. 找出所有可爲空的表中的所有列。
  2. 更新所有條目將可以爲空的所有列設置爲空。在這一步之後,應該沒有循環依賴(如果沒有,我認爲它們不能插入到表中)
  3. 找出它們的依賴並進行拓撲排序。
  4. 一一刪除。

我的問題是:

  1. 是否想法有意義嗎?
  2. 有沒有人做過類似的事情?如何?
  3. 如何查詢元表的第3步?因爲我對postgresql相當陌生。

任何想法和建議將不勝感激。

+0

我必須問 - *爲什麼*?這是一個非常奇怪的問題,它不是一項任務,就是你需要解決一些問題的一件事,你已經認定這是最好的解決方案,而且你正在問我們最佳解決方案的問題。如果是後者,它可能有助於解釋潛在的問題,也就是說,通過這樣做你最終想達到的目標。 –

+0

另外,通過「回滾」,你實際上是否意味着「刪除」?回滾意味着撤銷更改或恢復之前的內容。您似乎想要刪除可能具有相互依賴的外鍵關係的不同表中的一組行。 –

+0

@CraigRinger thx您的回覆。這不是一項家庭作業:)事實上,我正在處理一個導入/導出數據項目,系統中有很多表格,可能需要將數據導入/導出其中的一些表格。有一個功能是撤消輸入。所以我使用名稱'回滾',也許不是那麼正確:)任何方式,問題只是刪除一組行,如你所說 – jayven

回答

0

(1)和(2)不正確。很有可能會有列定義NOT NULL REFERENCES othertable(othercol) - 有任何正常的架構。

我認爲您需要做的是對外鍵依賴關係圖進行排序,找到允許您逐個表刪除需要刪除的數據的排序。請注意,由於延遲的外鍵約束,循環依賴關係是可能的,因此您需要降級/忽略DEFERRABLE INITIALLY DEFERRED約束;只要在COMMIT時間內再次保持一致,您可以暫時違反這些規定。

即使這樣你可能會遇到問題。如果客戶在交易過程中使用SET CONSTRAINTS來制定DEFERRABLE INITIALLY IMMEDIATE約束DEFERRED會怎麼樣?那麼你將無法應對循環依賴。要處理此問題,您的代碼必須[SET CONSTRAINTS ALL DEFERRED]才能繼續。

您需要查看information_schema或PostgreSQL特定的system catalogs來確定依賴關係。它也許值得一看pg_dump源代碼,因爲它會嘗試對轉儲表進行排序以避免依賴衝突。您將對pg_constraint 目錄或其information_schema等價物information_schema.referential_constraints,information_schema.constraint_table_usageinformation_schema.constraint_column_usage特別感興趣。可以使用information_schemapg_catalog。不要同時使用兩者。 information_schema是SQL標準,更便於攜帶,但查詢速度可能較慢,並且不具有pg_catalog包含的所有信息。另一方面,pg_catalog的模式不能保證在主要版本(如9.1到9.2)之間保持兼容 - 雖然它通常會這樣做 - 並且它的使用是不可移植的。

+0

對於'NOT NULL REFERENCES othertable(othercol)'(1)和(2)不會碰它,因爲它是不可以的。 – jayven

+0

我會檢查那些元表,很多thx – jayven