\ お問い合わせはこちら! /

【Django × Docker】開発中のマイグレーション不整合問題はどう対処する?DBを消す場合・消さない場合の整理

Django 開発でよく発生するのが、マイグレーションとデータベースの不整合
特に Docker でデプロイしながら開発していると、

  • ローカルでマイグレーションをやり直した
  • デプロイ先では古いマイグレーションが反映されたまま
  • InconsistentMigrationHistory などのエラーが出る

といった状況になりがちです。

結論として、判断基準の目安を示します。

判断基準おすすめ対応
まだ開発フェーズ/テストデータのみDBを削除
データに価値がある(本番やステージング)履歴を調整して整合性を取る
マイグレーションを大幅に作り直した開発段階なら「消す」、本番寄りなら「調整」

この記事では 「DBを消すべきケース」と「消さずに直すケース」 を整理し、それぞれの手順を端的にまとめます。

1. 開発初期でデータに価値がない場合

「まだ開発中」「テストデータしか入っていない」なら、マイグレーションを直すより DB を作り直したほうが早くて安全 です。

STEP

Docker の DB コンテナを停止

Bash
docker compose down
STEP

DBのVolume名を調べる

Bash
docker volume ls

出力例は以下の通り。

Bash
DRIVER    VOLUME NAME
local     db-data
local     static
local     some_other_volume

この中から削除対象の Volume を見つけましょう。

STEP

DB の Volume を削除

Bash
docker volume rm プロジェクト名_db-data

SQLite の場合は .sqlite3 ファイルを削除します。

STEP

再起動してマイグレーションを再実行

Bash
docker compose up -d
docker compose exec app python manage.py migrate
docker compose exec app python manage.py createsuperuser

これで 完全に新しいDB + 最新マイグレーション 状態になります。

2. データを消したくない場合

本番寄りの環境では、DB を消すと消えて困るデータがある場合が多いです。

この場合は、履歴を合わせていきます。

STEP

現在 DB に適用済みのマイグレーションを確認

Bash
python manage.py showmigrations app_name
STEP

Django 側で「適用済みとして扱う」(–fake)

DB にはカラムがあるのに Django 側では未適用扱いのケース。

Bash
python manage.py migrate app_name 0005_add_field --fake

Django に「実際にはもう適用されている」と教えて履歴を揃えます。

--fakeはスキーマには手をつけず、履歴だけを揃えます。

STEP

必要なら追加でマイグレーションを作る

Bash
python manage.py makemigrations
python manage.py migrate
STEP

複雑に壊れている場合は手書きマイグレーションで調整

“モデルとDBを一致させるためのマイグレーション” を作ります。

  • RenameField
  • RemoveField
  • AlterField

上記などを使うことになります。

補足:安全にDBを削除するための注意点

開発中とはいえ、docker volume rmデータベースを完全消去する破壊的操作 です。

以下の点を押さえておくと、安全に作業できます。

「本当に消して良いDBか?」を必ず確認する

docker volume rm xxx_db-data元に戻せません

  • チーム開発なら、他メンバーが使っている DB を消さないよう注意
  • 本番やステージングの volume 名と似ていると事故の元
  • 削除前に必ず volume 一覧で 対象の volume 名を再確認
Bash
docker volume ls

意図しない volume を消すミスが最も多いため、慎重に確認してください。

データのバックアップを取っておくと安心

万が一間違ってDBを消しても復元できるよう、削除前にバックアップを取るのが理想です。

PostgreSQL の例

Bash
pg_dump -h localhost -U postgres -d mydb > backup.sql

SQLite の例

Bash
cp db.sqlite3 db-backup.sqlite3

再現性のために「初期化スクリプト」を準備するのも有効

開発では DB を消す作業が何度も発生するので、次のようなスクリプトを用意しておくと良いです。

Bash
#!/usr/bin/env bash
set -e

docker compose down
docker volume rm project_db-data
docker compose up -d

docker compose exec app python manage.py migrate
docker compose exec app python manage.py loaddata initial_data.json

環境構築が一瞬で終わります。

マイグレーション履歴を消す場合の注意点

DB の volume を削除すると同時に、migrations/ ディレクトリを整理したいケースもあります。

その際の注意事項は次の通りです。

  • migrations/__init__.py だけは必ず残す(これがないとアプリが migration パッケージとして認識されない)
  • チーム開発では、勝手に migration を消すと履歴が他メンバーとズレる
  • Git で migration を削除する際は、全員で一斉に migration をリセットするタイミングを揃える

不要なマイグレーションの削除例

Bash
rm app_name/migrations/000*.py
touch app_name/migrations/__init__.py

その後、新しく作り直します。

Bash
python manage.py makemigrations
python manage.py migrate

これらの補足を押さえておくと、開発フェーズでも安全にマイグレーションの再構築が行えます。

まとめ

Django × Docker の開発では、マイグレーション不整合はほぼ必ず起きます。

  • 消してよいDBか? 残すべきDBか?
  • 「速く直す」か「丁寧に直す」か?

大事なのは、上記を状況で切り分けることが必要です。

この記事が気に入ったら
フォローしてね!

シェア・記事の保存はこちら!

この記事を書いた人

CFXLOGのアバター CFXLOG プログラマ

メイン言語はPython。本ブログでは、実務や普段の学習で学んだことをアウトプットしています。
基本情報技術者試験合格者。

コメント

コメントする

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)