はじめに
ちょっとわけあって、PostgreSQLの一部のデータをあるDBから別のDBにコピーする必要がありました。
そのときに使ったコマンドをメモしておきます。
特定のテーブルの一部のデータをエクスポートする
psqlを実行するマシンとDBサーバーが同一の場合
psqlのコンソールからCOPYコマンドを実行し、適当なファイルにデータを出力する。
COPY (SELECT * FROM users WHERE status = 'active') TO '/tmp/users.csv' WITH CSV HEADER;
psqlを実行するマシンとDBサーバーが異なる場合
ターミナル上からpsqlコマンドでCSVデータを標準出力に出力し、その内容を適当なファイルにリダイレクト(>
)する。
# 一時的にDB接続用のパスワードを環境変数にセット(historyに残らないように先頭にスペースを入れる)
export PGPASSWORD=password1234
psql \
-c "COPY (SELECT * FROM users WHERE status = 'active') TO STDOUT WITH CSV HEADER;" \
-h your-host-name \
-U your-user-name \
-d your-db-name > /tmp/users.csv
上記の方法でエクスポートしたデータをインポートする
インポートしたデータは既存のテーブルに追記される。(全データが置きかわるわけではない)
そのため、ユニーク制約等に違反すると取り込めない(はず)。
注意点
データのインポートはいきなり本番環境で実行したりせず、まずローカルやステージング環境で試して期待どおりのインポートが行われるか検証しましょう。
また、本番環境でインポートする場合は万が一のトラブルに備えて、インポート前にデータベースのバックアップを取っておきましょう。
免責事項
本コマンドを参考にして何らかの損害が発生したとしても、筆者はいかなる責任も負いません。
psqlを実行するマシンとDBサーバーが同一の場合
psqlのコンソールからCOPYコマンドを実行する。
COPY users FROM '/tmp/users.csv' (FORMAT CSV, HEADER true);
psqlを実行するマシンとDBサーバーが異なる場合
標準入力経由でCSVファイルの内容をpsqlのCOPYコマンドに引き渡す。
# 一時的にDB接続用のパスワードを環境変数にセット(historyに残らないように先頭にスペースを入れる)
export PGPASSWORD=password1234
cat /tmp/jit_test.csv | \
psql -c "COPY users FROM STDIN (FORMAT CSV, HEADER true);" \
-h your-host-name \
-U your-user-name \
-d your-db-name
おまけ:特定のテーブル(複数)をダンプ・リストアする
上記のユースケースとは別に、特定のテーブル(複数)を全件ダンプし、リストアする場合のコマンド例。
# 一時的にDB接続用のパスワードを環境変数にセット(historyに残らないように先頭にスペースを入れる)
export PGPASSWORD=password1234
# users、companies、ordersの3テーブルをダンプする
pg_dump \
--column-inserts \
-t users -t companies -t orders \
-h your-host-name \
-U your-user-name \
-d your-db-name
> /tmp/dump.sql
# ダンプからリストアする(users、companies、ordersの3テーブルがリストアされる)
psql \
-h your-host-name \
-U your-user-name \
-d your-db-name
< /tmp/dump.sql