私はPostgresを使用していますが、CSVファイルから取得する大きな更新クエリを作成したいと思います。(id, banana, Apple)
。
リンゴではなくバナナを変更するアップデートを実行したいと思います。新しいバナナとそのIDはそれぞれCSVファイルになります。
Postgresのサイトを見てみましたが、例は私を殺しています。
COPY
ファイルを一時的なステージングテーブルに追加し、そこから実際のテーブルを更新します。好む:
CREATE TEMP TABLE tmp_x (id int, Apple text, banana text); -- but see below
COPY tmp_x FROM '/absolute/path/to/file' (FORMAT csv);
UPDATE tbl
SET banana = tmp_x.banana
FROM tmp_x
WHERE tbl.id = tmp_x.id;
DROP TABLE tmp_x; -- else it is dropped at end of session automatically
インポートされたテーブルが更新されるテーブルと正確に一致する場合、これは便利です。
CREATE TEMP TABLE tmp_x AS SELECT * FROM tbl LIMIT 0;
制約なしで、既存のテーブルの構造と一致する空の一時テーブルを作成します。
SQL COPY
には、このためのスーパーユーザー権限が必要です。 ( マニュアル ):
COPY
ファイルまたはコマンドの名前付けは、サーバーがアクセスする権限を持つファイルの読み取りまたは書き込みを許可するため、データベースのスーパーユーザーにのみ許可されます。
psqlメタコマンド\copy
はすべてのdbで機能します役割。 マニュアル:
フロントエンド(クライアント)コピーを実行します。これは、SQL
COPY
コマンドを実行する操作ですが、サーバーが指定したファイルを読み書きする代わりに、psqlはファイルを読み書きし、サーバーとサーバー間でデータをルーティングします。ローカルファイルシステム。これは、ファイルのアクセス可能性と特権がサーバーではなくローカルユーザーのものであり、SQLスーパーユーザー特権が必要ないことを意味します。
一時テーブルのスコープは、単一ロールの単一セッションに制限されているため、上記は同じpsqlセッションで実行する必要があります。
CREATE TEMP TABLE ...;
\copy tmp_x FROM '/absolute/path/to/file' (FORMAT csv);
UPDATE ...;
これをbashコマンドでスクリプト化する場合は、必ずすべてをsinglepsql呼び出しでラップしてください。好む:
echo 'CREATE TEMP TABLE tmp_x ...; \copy tmp_x FROM ...; UPDATE ...;' | psql
通常、メタコマンド\\
を使用してpsqlメタコマンドとpsqlのSQLコマンドを切り替える必要がありますが、\copy
はこのルールの例外です。再びマニュアル:
\copy
メタコマンドには特別な解析ルールが適用されます。他のほとんどのメタコマンドとは異なり、行の残りの部分全体は常に\copy
の引数とみなされ、変数の補間や逆引用符の展開は引数で実行されません。
インポートテーブルが大きい場合は、セッションの一時的にtemp_buffers
を増やすと料金がかかる場合があります(セッションの最初のもの)。
SET temp_buffers = '500MB'; -- example value
一時テーブルにインデックスを追加します。
CREATE INDEX tmp_x_id_idx ON tmp_x(id);
一時テーブルはautovacuum/auto-analyzeでカバーされないため、手動で ANALYZE
を実行します。
ANALYZE tmp_x;
関連する回答: