はじめに
stg環境などで不具合が発生した場合、その原因をlocal環境で調査するために、該当環境のデータベース全体をダンプし、local環境へインポートすることが必要になるケースがあります。
しかし、Prismaで enum を使用している場合、TablePlusなどのGUIツールを使ったエクスポート → インポートでは正常に動作しないことがありました。
enum Weekday {
MONDAY
TUESDAY
WEDNESDAY
THURSDAY
FRIDAY
SATURDAY
SUNDAY
}
ERROR: type "_weekday" does not exist
LINE 75: "business_days" _Weekday DEFAULT ARRAY[]::"Weekday"[],
この問題への対応策として、以下の2つの方法が考えられます:
- SQLを直接修正する
- PostgreSQLのコマンドを使用してダンプを取得する
今回は、 後者のPostgreSQLのコマンドを使用してデータをダンプし、それをlocal環境へインポートする方法を選択しました。
以下に、その具体的な手順を記載します。
環境
- macOS Sonoma 14.3.1
- PostgreSQL 15.10
手順
1. PostgreSQLのインストール
# PostgreSQLのインストール
$ brew install postgresql@15
# PATHの設定(M1/M2 Mac用)
$ echo 'export PATH="/opt/homebrew/opt/postgresql@15/bin:$PATH"' >> ~/.zshrc
$ source ~/.zshrc
2. データベースのfull dump取得
password
にはデータベースのパスワードを入れてください。
また、実際のコマンドに[]
は不要です。
PGPASSWORD="password" pg_dump \
--clean \
--if-exists \
--no-owner \
--inserts \
--no-tablespaces \
--no-acl
"postgresql://[username]@[hostname]/[database]?sslmode=require" > full_dump.sql
オプションの説明(ref: pg_dump)
-
--clean
: データベースオブジェクトを作成するコマンドの前に、データベースオブジェクトを整理(削除)するコマンドを書き出します。 (--if-existsも指定されなければ、リストア先のデータベースの中に存在しないオブジェクトがある場合に、害がないエラーがいくつか発生するかもしれません。) -
--if-exists
: データベースオブジェクトを初期化するときに、条件コマンドを使います(つまり、IF EXISTS句を追加します)。 -
--no-owner
: オブジェクトの所有権を元のデータベースにマッチさせるためのコマンドを出力しません。 デフォルトでは、pg_dumpは、ALTER OWNER文またはSET SESSION AUTHORIZATION文を発行して、作成したデータベースオブジェクトの所有権を設定します。 -
--inserts
: データを(COPYではなく)INSERTコマンドの形式でダンプします。 これを行うとリストアに非常に時間がかかります。 主にPostgreSQL以外のデータベースへロード可能なダンプを作成する時に有用です。 しかし、このオプションは各行に対して別々のコマンドを生成しますので、一行を再ロードする時にエラーになったとしても、テーブルの内容まるごと失われることなく、一行のみが失われるだけですみます。 列の順序を変更した場合はリストアが失敗する可能性があることに注意してください。 --column-insertsはさらに処理が遅くなりますが、列の順序変更に対して安全です。 -
--no-tablespaces
: テーブル空間を選択するコマンドを出力しません。 このオプションを使用すると、すべてのオブジェクトはリストア時のデフォルトのテーブル空間の中に作成されます。 -
--no-acl
: アクセス権限(grant/revokeコマンド)のダンプを抑制します。(これがないとERROR: role "neon_superuser" does not existになります)
3. インポート
TablePlusなどでGUIから取得したfull_dump.sqlをインポートすれば完了です。
まとめ
Neon.techのPostgreSQLからダンプを取得する際は
-
pg_dump
を使用する - 必要なオプションを指定してダンプを実行