0

SQL スクリプトを使用して DB を復元しようとしていますが、外部キー制約が邪魔になります

MySQL DB を PostgreSQL に移行します。MySQL の create table 構文がかなり異なってしまったので、スキーマは同じだがデータが異なる別の PostgreSQL DB を取得し、そこからスキーマのみを復元しました。言い換えれば、テーブル、制約、シーケンス、およびそのすべてを含むデータベースがありますが、内部にはデータがありません。

それで、データを復元する時が来ました。SQL スクリプトとして phpMyAdmin (データのみ) を使用して MySQL DB のバックアップを取り (pgAdmin は何らかの理由で zip または gzip ファイルを受け入れないようです)、SQL スクリプトを実行します。さて、ここで問題が発生し始めます。これは当然のことです。MySQL から PostgreSQL に移行するので、構文エラーは必ず発生します。

ただし、次のような、構文に関連しない他の問題があります。

ERROR: insert or update on table "_account" violates foreign key constraint "fk_1_account"
DETAIL:  Key (accountid)=(2) is not present in table "_entity".

つまり、基本的に外部制約が存在し、クエリはデータを_accountテーブルに挿入しようとしていますが、対応するデータはまだテーブルに挿入されて_entityいません。どうすればそれを回避できますか?pgAdmin3/PostgreSQL ですべての制約を無効にし、データを挿入してから、制約を再度有効にする方法はありますか?

私が遭遇した構文関連のエラーは、これでした:

 INSERT INTO _accounttype_seq (id) VALUES (11);

そのステートメントに相当するPostgreSQL(私が正しければ)は

 ALTER SEQUENCE _accounttype_seq INCREMENT BY 11; 

ただし、スクリプト全体を実行して、200 以上の Sequence 挿入ステートメントをすべて変更するのは少し面倒です。ここでは怠惰ですが、シーケンスを処理する簡単な方法はありますか?

または、これを簡単にするための別のツールセットについて何か提案はありますか?

お時間をいただきありがとうございます。よい一日を。

4

2 に答える 2

2

明らかに、MySQL で外部キーが実際に強制されていなかったか (おそらく MyISAM を使用しているため)、生成された SQL が間違った順序で実行されているだけです。

それが「ただ」間違った順序である場合、2 つの解決策が考えられます。

  1. 生成されたスクリプトを編集し、すべての FK 定義をスクリプトの最後に移動します。
  2. 各 FK コンストレイントの定義を編集し、それらをすべて に設定しますinitially deferred。次に、スクリプトを 1 つのトランザクションとして実行し、最後にコミットするだけにします。

編集(コメントするには多すぎるため)

を使用SET CONSTRAINTS ALL DEFERREDすると、制約がオプションで作成された場合にのみ機能しますDEFERRABLE

すべてを 1 つのトランザクションで実行するには、自動コミットをオフにする必要があります。次に、単にINSERTs を実行し、最後に a を発行しCOMMITます。A;は、自動コミットをオンにしている場合にのみコミットします。

自動コミット設定から独立したい場合は、スクリプトを開始[BEGIN][1]し、最後に COMMIT が 1 つしかないことを確認してください。

BEGIN DEFERRABLE
   INSERT INTO table_one ... ;
   INSERT INTO table_two ... ; 
   .....
COMMIT;
于 2011-11-01T17:10:59.743 に答える
2

外部キー制約を回避しようとしないでください。これは、データが正しくないことを確認する方法です。

最初に制約を見て、正しい順序でテーブルに挿入していることを確認してください。_entity が "_account の親である場合は、最初に入力する必要があります。

次に、失敗したレコードを例外テーブルに移動するスクリプトを作成する必要があります。次に、それらを見て、データの整合性の問題が何であるかを確認し、レコードを永久に破棄する必要があるかどうか、または欠落している親の値を特定する必要があるかどうかを確認できます。顧客が存在しなくなった注文などの重要なデータであり (そもそも正しい fk を持たないシステムでは可能性があります)、記録を保持する必要があり、親の値がどうあるべきか判断できない場合は、作成できます。顧客テーブルの「不明」レコードを作成し、すべての不良注文をその顧客 ID に割り当てます。

また、変更シーケンスを手動で変更するのは、退屈だとしてもそれほど時間はかかりません。このタイプの変換では、手動で処理する必要があるものが他にもたくさんあります。

私は PostgreSQL 用のデータ インポート ツールを見つけようとします。私は SSIS を使用する SQL サーバーの世界に住んでいますが、PostgreSQL の世界には SSIS と同等のものが必要です。

于 2011-11-01T18:18:58.567 に答える