こんにちは、かつコーチです。
チーム開発でDjangoを使っていると、ある日突然マイグレーションが動かなくなることがあります。
筆者はチームで開発していたとき、自分のブランチでgit pullした直後にmigrateを実行したら、見たことのないエラーで画面が埋め尽くされて焦った経験があります。
この記事では、複数人開発でとくに発生しやすいマイグレーションの競合について、実際に起きがちなエラーメッセージを引用しながら原因と対処法を解説します。
マイグレーション競合はなぜ起きるのか
マイグレーションファイルは「連番の履歴」である
Djangoのマイグレーションとは、モデルの変更内容をDBに反映するための「変更履歴ファイル」です。0001_initial.py、0002_xxx.pyのように連番で管理されており、Djangoはこの順番通りに適用していく前提で動いています。
複数人が同時に同じアプリでマイグレーションを作ると起きる
問題は、複数人が同じタイミングで同じアプリのマイグレーションを追加したときに起きます。
例えばAさんとBさんが同時にblogアプリのモデルを変更し、それぞれの手元でmakemigrationsを実行したとします。
どちらの手元でも「前のマイグレーションの次は自分の変更」という認識になるため、Aさんは0005_add_author.py、Bさんも同じく0005_add_thumbnail.pyのように、同じ番号のファイルが2つできてしまうのです。
先にpushした方が正になり、後からpullした方は自分の環境と履歴が食い違った状態になります。
よくあるつまずきポイント・エラー対処
Conflicting migrations detected
❌Before
git pullした後にmakemigrationsを実行すると、次のようなエラーが出ます。
CommandError: Conflicting migrations detected; multiple leaf nodes in the migration graph: (0005_add_thumbnail, 0005_add_author in blog).
To fix them run 'python manage.py makemigrations --merge'
これは「マイグレーションの履歴が枝分かれ(2つの最新地点=leaf nodeが存在)している」という意味です。
筆者はこのメッセージを見た瞬間、自分のモデル定義が壊れたのかと思い込みましたが、実際は履歴の分岐が原因で、モデル自体は正常でした。
✅After
Djangoが親切にも解決コマンドを教えてくれているので、その通りに実行します。
python manage.py makemigrations --merge
これを実行すると、2つの分岐をまとめるマージ用マイグレーション(例:0006_merge_20260831_1200.py)が自動生成されます。
中身を確認し、問題なければそのままmigrateを実行します。
python manage.py migrate
マージ後もmigrateでエラーが出るケース
マージしても、両方のマイグレーションが同じカラムを別々の方法で追加しているような場合、以下のようなエラーが出ることがあります。
django.db.utils.OperationalError: duplicate column name: thumbnail
これは、すでにAさんの変更でthumbnailカラムが追加されているDBに対して、Bさんのマイグレーションが同じカラムを再度追加しようとした場合に起きます。
✅After
この場合は自動マージに頼らず、以下の手順で手動整理するのが確実です。
- 重複している変更内容を関係者間で確認する
- 片方のマイグレーションファイルを削除、または
--fakeオプションで「実行済み扱い」にする
# すでに手元のDBには反映済みの変更を、実行済みとして記録だけする
python manage.py migrate blog 0005_add_thumbnail --fake
--fakeは「DBには何もしないが、Djangoの管理台帳上は適用済みとして記録する」オプションです。
安易に使うとDBの実態とマイグレーション履歴がズレるため、内容を完全に理解した上でのみ使いましょう。
応用・一歩先の使い方
競合を未然に防ぐチーム開発のルール
競合そのものをゼロにはできませんが、発生頻度を下げる工夫はできます。
- モデルを変更したら、その日のうちに
makemigrationsして早めにpushする - 大きな機能追加の前にチームで一声かけ、マイグレーションが重ならないタイミングを揃える
git pull直後は必ずshowmigrationsで状態を確認してから作業を始める
python manage.py showmigrations blog
このコマンドで、適用済み([X])・未適用([ ])のマイグレーションを一覧確認できます。
マージコミットを作ったらチームに共有する
--mergeで作られたマイグレーションファイルは、必ずコミットしてpushしましょう。
自分のローカルだけでマージを解決して満足してしまい、他のメンバーが再び同じ競合にぶつかる、というのはチーム開発でよくある事故です。
まとめ
この記事のポイント
- マイグレーション競合は、複数人が同時に同じアプリの変更を加えたときに発生する
Conflicting migrations detectedが出たらmakemigrations --mergeで解決を試みる- カラム重複などマージで解決できない場合は
--fakeオプションも選択肢になる showmigrationsで現在の適用状況をこまめに確認する習慣が予防につながる
次に読むべき記事
マイグレーション自体の基本操作をおさらいしたい場合は、「makemigrations/migrateの基本:モデルをDBに反映する」の記事もあわせてご覧ください。
タグ: Django, 中級者向け, エラー解決