0

異なるテーブルからのエントリのバッチに対して「ロールバック」(通常のロールバックではない)関数を実装するタスクがあります。例えば:

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

各table_nameのエントリを削除する必要があります。しかし、これらのエントリは非常に複雑な関係にある可能性があるためです。私の考えはいくつかのステップにあります:

  1. null許容可能なすべてのテーブルからすべての列を見つけます。
  2. すべてのエントリを更新して、null許容のすべての列をnullに設定します。このステップの後、循環依存はないはずです(そうでない場合は、テーブルに挿入できないと思います)
  3. それらの依存関係を見つけて、トポロジカルソートを作成します。
  4. 1つずつ削除します。

私の質問は次のとおりです。

  1. アイデアは理にかなっていますか?
  2. 誰かが以前に似たようなことをしたことがありますか?そしてどうやって?
  3. ステップ3のメタテーブルをクエリする方法は?coz私はpostgresqlを初めて使用します。

任意のアイデアや提案をいただければ幸いです。

4

1 に答える 1

0

(1)と(2)は正しくありません。定義された列がある可能性が非常に高いですNOT NULL REFERENCES othertable(othercol)-通常のスキーマにあります。

私があなたがする必要があると思うのは、外部キー依存関係グラフをソートして、DELETE削除する必要のあるデータをテーブルごとに並べ替えることができる順序を見つけることです。外部キー制約が延期されるため、循環依存が発生する可能性があるため、制約を降格/無視する必要があることに注意してくださいDEFERRABLE INITIALLY DEFERRED。一度にすべてが再び一貫している限り、一時的にそれらに違反することができますCOMMIT

それでも、問題が発生する可能性があります。クライアントがトランザクション中に制約SET CONSTRAINTSを作成していた場合はどうなりますか?そうすると、循環依存に対処できなくなります。これを処理するには、先に進む前にコードを[]する必要があります。DEFERRABLE INITIALLY IMMEDIATEDEFERREDSET CONSTRAINTS ALL DEFERRED

依存関係を理解するには、information_schemaまたはPostgreSQL固有のシステムカタログを確認する必要があります。pg_dump依存関係の競合を回避するためにダンプされたテーブルを並べ替えようとするため、ソースコードも一見の価値があります。pg_constraint カタログ、またはそれにinformation_schema相当するものinformation_schema.referential_constraintsinformation_schema.constraint_table_usageおよびに特に関心がありinformation_schema.constraint_column_usageます。

information_schemaまたはのいずれかを使用できますpg_catalog。両方を使用しないでください。information_schemaはSQL標準であり、より移植性がありますが、クエリが遅くなる可能性があり、すべての情報が含まれているわけではありませんpg_catalog。反対に、pg_catalogのスキーマはメジャーバージョン(9.1から9.2など)間で互換性を維持することが保証されていません(通常は互換性がありますが)。また、その使用は移植性がありません。

于 2012-10-15T11:10:05.160 に答える