MySQL からのレコードがたくさんあります。ActiveRecordを使用してPostgreSQLに正常に挿入されるように、データをマッサージしました。これは、行単位、つまり一度に 1 行ずつ挿入することで簡単に行うことができます。これは非常に遅いです一括挿入を行いたいのですが、行のいずれかに無効なデータが含まれていると失敗します。とにかく、一括挿入を実現でき、一括全体ではなく無効な行のみが失敗することはありますか?
2 に答える
コピー
SQLCOPY
を一括挿入 (または\copy
psql クライアントで同等のもの) に使用する場合、失敗は許されません。COPY
不正な行をスキップできません。入力形式をインポート先のテーブルに一致させる必要があります。
データ自体 (デコレータではない) がテーブル定義に違反している場合、これをより寛容にする方法があります。例: type のすべての列を含む一時ステージング テーブルを作成しますtext
。それに COPY し、問題のある行を SQL コマンドで修正してから、実際のデータ型に変換して実際のターゲット テーブルに挿入します。
この関連する回答を検討してください:
PostreSQL で新しい行のみを一括挿入する方法
または、このより高度なケース:
PostgreSQL COPY を使用する場合の「エラー: 最後の予期された列の後に余分なデータ」
NULL
値が不適切な場合は、ターゲット テーブルから NOT NULL 制約を一時的に削除します。COPY の後に行を修正してから、制約を元に戻します。または、ルールを一時的に緩和する余裕がない場合は、ステージング テーブルを使用する方法を選択してください。
サンプルコード:
ALTER TABLE tbl ALTER COLUMN col DROP NOT NULL;
COPY ...
-- repair, like ..
-- UPDATE tbl SET col = 0 WHERE col IS NULL;
ALTER TABLE tbl ALTER COLUMN col SET NOT NULL;
または、ソース テーブルを修正するだけです。COPY は、問題のある行の番号を示します。お好みのエディターを使用して修正し、再試行してください。私はそれに使うのが好きvim
です。
INSERT
INSERT
(コメントのように)値のチェックはNULL
簡単です:
値のある行をスキップするにはNULL
:
INSERT INTO (col1, ...
SELECT col1, ...
WHERE col1 IS NOT NULL
sth を挿入します。値の代わりにelse NULL
(私の例では空の文字列):
INSERT INTO (col1, ...
SELECT COALESCE(col1, ''), ...
これに対する一般的な回避策は、制約なしでTEMPORARY
またはテーブルにデータをインポートすることです。入力のデータが十分に偽物である場合は、型付き列です。UNLOGGED
text
次にINSERT INTO ... SELECT
、データに対してクエリを実行して、インポート中にデータをクリーンアップする大きなクエリを実際のテーブルに入力できます。これには多くのCASE
ステートメントを使用できます。アイデアは、データを 1 回のパスで変換することです。
Ruby でデータを読み取り、COPY ... FROM STDIN
. これは Ruby のPg
gem で可能です。たとえばhttps://bitbucket.org/ged/ruby-pg/src/tip/sample/copyfrom.rbを参照してください。
より複雑なケースについては、Pentaho Kettle または Talend Studio ETL ツールを参照してください。