既存DBを使っている Django プロジェクトで、
models.py と DB、migration の状態が食い違った時は、
下手にやり直すと一気に泥沼化する。
この記事では、実際に起きたトラブルを元に、
- 何が原因でズレるのか
- どのエラーは「正常なサイン」なのか
- DBを壊さずにどう整合を取り直すか を 再現性のある手順としてまとめる。
想定シナリオ
- 既存 MySQL にすでに複数テーブルが存在
- Django アプリは後付け or 途中から migration 管理
- 新しく Media / MediaFolder テーブルを追加したい
- migrate 実行時に already exists エラーが出る
Djangoにおける「真実の源泉」
まず大前提。
DjangoはDBを直接信用しない
Djangoが信じているのは この2つだけ。
- migrations/*.py ファイル
- DB内の django_migrations テーブル
DBにテーブルが存在するかどうかは見ていない
ここを理解していないと、必ず詰まる。
よくある地雷①
既存DBがあるのに 0001_initial.py に後からモデルを追加する
これは ほぼ確実に事故る。
結果:
- Django「全部もう作成済みのはず」
- DB「そんなテーブルは無い」
またはその逆。
正しい考え方
- 0001_initial.py は 過去の歴史
- 一度適用されたら二度と触らない
- 新しいテーブルは 必ず新しい migration
既存DBに新テーブルを追加する正攻法
- `models.py` は最終形にする
サンプルコード
- 空の migration を作る
- migration ファイルを手で書く
⚠ Media / MediaFolder 以外は絶対に入れない
migrate 時に出る典型エラーと意味
❌ NameError: models is not defined
→ migration ファイルの import 不足
❌ NameError: django is not defined
→ これが無い
❌ Table 'app_post' already exists
→ migration に Post の CreateModel が混入している
migration を修正するべきエラー
❌ Table 'app_media' already exists
→ DBにはあるが migration は未適用
これは 正常な到達点。
--fake を使うべきタイミング
使っていい条件
DB構造が正しい
しかし migration 履歴だけが追いついていない
👉 SQLは流さず、履歴だけ進める
使ってはいけないケース
- migration の内容が間違っている
- 不要な CreateModel が含まれている
この場合は migration 修正が先
正常な最終状態の確認
- Django管理画面:正常
- CRUD:正常
- migrate 再実行:何も起きない
migration ファイルは保存すべき?
結論:必ず保存・Git管理する
保存すべきもの:
理由:
- Djangoは migration を 設計図として使う
- Docker再ビルドでも必須
- MySQL が別コンテナでも必須
まとめ(実務的チェックリスト)
- 0001_initial.py は触らない
- 新規テーブルは必ず新 migration
- already exists は ゴール直前のサイン
- --fake は「DBは正しい時」だけ使う
- migrations は Git 管理必須
おわりに
Django の migration トラブルは
「仕組みを知らないと解決不能」だが、
理解すると完全に制御できる。
今回のケースは、
- DBを壊さず
- 履歴を正しく残し
- 将来の再ビルドにも耐える
という意味で 理想的な解決パターン。
同じ状況に遭遇した未来の自分へ向けた、
実践的な備忘録としてここに残しておく。





