はじめに
stg環境やprod環境のdumpファイルを取得して、ローカルに適用したいが、データ構造が異なるという状況が以前ありました。よく考えるとこれは頻繁に起こりうることだと思います。
私自身dumpファイルの適用自体が1, 2回くらいしか経験がなかったのもあり、その時は少し詰まってしまったので、dumpファイルの適用方法についてまとめてみました。
前提
- Dockerを使用して開発していることを想定
- DBは PostgreSQL を想定
- dumpは pg_dump で取得したカスタム形式(.dump)を想定
準備
dumpファイルの作成
Dockerコンテナ内のDBからdumpを取得する場合は、以下のコマンドで取得できます。
docker exec -t [DBコンテナ名] \
pg_dump -U postgres -d develop -F c \
-f /tmp/develop.dump
dumpファイルの移動
例えば、本番環境などでdumpファイルを作成した場合、手元に持ってきたときに最初はホスト側にdumpファイルがあるはずです。
しかし、Docker内にファイルを移動したいということも多いです。そのような場合はdocker cpコマンドを使用します。
docker cp ./[dumpファイル名].dump \
example-api-1:[copy後dumpファイル名].dump
DBコンテナ名の確認
DockerのDBコンテナにdumpファイルを適用するためには、先にDBコンテナ名を把握しておく必要があります。
DBコンテナ名は以下のコマンドで確認することができます。
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
742f6aa46f68 example-api "/bin/sh -c 'echo Co…" 2 days ago Up About an hour 0.0.0.0:3001->3000/tcp example-api-1
140abbec419e postgres:16.2-alpine "docker-entrypoint.s…" 2 days ago Up About an hour (healthy) 0.0.0.0:5432->5432/tcp example-db-1
NAMES 列がコンテナ名です。
この例では example-db-1 が DB コンテナになります。
dumpファイルの適用方法
1. 取得元と適用先でDB構造が同じとき
既存DBをすべて削除してからまっさらなDBを作成し、dumpファイルの中身をそのまま再現します。
① 既存 DB を強制削除
docker exec -i [DBコンテナ名] \
psql -U postgres -d postgres \
-c "DROP DATABASE IF EXISTS develop WITH (FORCE);"
② DB を作り直す(※ dump に DB 作成が含まれていない場合)
docker exec -i [DBコンテナ名] \
createdb -U postgres develop
※ pg_restore で -C を使う場合は不要なこともあります
(dump の作り方次第)
③ dumpの中身をそのまま適用する
a. dump が コンテナ内にある場合
docker exec -i [DBコンテナ名] \
pg_restore --verbose --no-owner \
-U postgres -d develop \
[dumpファイル名].dump
b. dump が ホスト側にある場合
docker exec -i [DBコンテナ名] \
pg_restore --verbose --no-owner \
-U postgres -d develop \
< [dumpファイル名].dump
2. 取得元と適用先でDB構造が異なるとき
① migration を実行して DB を空にする
npx prisma migrate reset --skip-seed
- ローカルの migration に基づいて schema を再構築
- データは空の状態になる
② dumpのデータのみを適用する
a. dump が コンテナ内にある場合
docker exec -i [DBコンテナ名] \
pg_restore -U postgres -d develop \
--data-only \
--disable-triggers \
--no-owner --no-privileges \
/[dumpファイル名].dump
b. dump が ホスト側にある場合
docker exec -i [DBコンテナ名] \
pg_restore -U postgres -d develop \
--data-only \
--disable-triggers \
--no-owner --no-privileges \
< [dumpファイル名].dump
まとめ
本番環境などのdumpデータを取得してローカルに反映するような状況では、必ずしもデータ構造が同じではないと思うので、気をつけましょう!
| 状況 | 方針 |
|---|---|
| 構造が同じ | DBごと削除 → そのままrestore |
| 構造が違う | migrationでschema構築 → data-only restore |
株式会社シンシア
株式会社シンシアでは、実務未経験のエンジニアの方や学生エンジニアインターンを採用し一緒に働いています。
※ シンシアにおける働き方の様子はこちら
弊社には年間100人程度の実務未経験の方に応募いただき、技術面接を実施しております。
この記事が少しでも学びになったという方は、ぜひ wantedly のストーリーもご覧いただけるととても嬉しいです!