こんにちは!
「【個人開発】Djangoとは何か?初心者のための基本とサンプルコードを図解しながら実装する」の記事を読んでいただきありがとうございます。
Djangoでのアプリケーション開発において、モデルは時間の経過とともに変化していきます。
新しい機能追加や要件変更に伴い、データベース構造の変更が必要になることはよくあります。
この記事では、Djangoのマイグレーションとは何か、なぜそれが必要なのか、そして基本的な使い方と実践で役立つ注意点について、初心者にも分かりやすく解説します。
マイグレーションの基本
マイグレーションとは、Djangoのモデル変更をデータベースに反映する仕組みです。モデルを変更した後、次のコマンドでマイグレーションファイル作成 / 適用を行います。
#マイグレーションファイルを作成します。
python manage.py makemigrations
#作成したマイグレーションをデータベースに適用するには。
python manage.py migrate
なぜDjangoのマイグレーションが必要なのか
マイグレーションの必要性を簡潔に説明
Djangoのマイグレーションは、「コードとしてのデータベース」を実現するための仕組みです。
では、なぜこれが必要なのでしょうか?
1. モデル変更の追跡と共有
あなたがPythonコードでモデルを変更しても、データベース自体は自動的に変わりません。
例えば以下の例を見てみましょう。
# 変更前
class Product(models.Model):
name = models.CharField(max_length=100)
price = models.DecimalField(max_digits=10, decimal_places=2)
# 変更後(descriptionフィールドを追加)
class Product(models.Model):
name = models.CharField(max_length=100)
price = models.DecimalField(max_digits=10, decimal_places=2)
description = models.TextField() # 新しいフィールド
この変更をデータベースに反映するには、SQLを手動で書く必要がありますが、これは面倒で間違いやすいプロセスです。
マイグレーションはこれを自動化します。
参考:この変更をSQLで表現すると
PostgreSQLの場合
-- テーブルにdescriptionカラムを追加
ALTER TABLE app_product
ADD COLUMN description TEXT;
MySQLの場合
ALTER TABLE app_product
ADD COLUMN description TEXT NOT NULL;
その他考慮しなければいけない点
NULL許容/非許容 : 既存データがあるテーブルにNOT NULL制約付きのカラムを追加するには、デフォルト値の指定が必要です。
インデックスの再作成 : テーブル構造を変更する場合、インデックスも適切に更新する必要があります。
本番環境への適用 : もしテーブルの構造を変えた時に、そもそも開発環境で実行したSQLを本番環境でも適用しても大丈夫でしょうか?という不安がつきまといます。
2. チーム開発をスムーズにする
複数の開発者がいる場合には、考慮しなければならないこともあります。
例えば、以下のような点です。
- Aさんがモデルを変更してデータベースも更新
- BさんがAさんのコードを取得しても、Aさんがどのようにデータベースを変更したかは分からない
マイグレーションファイルがあれば、Bさんは単に [ python manage.py migrate ]を実行するだけで、Aさんと同じデータベース構造にできます。
3. デプロイの安全性を高める
開発環境から本番環境へのデプロイ時、モデル変更をどう適用するか?
- 手動でSQLを実行?(リスクが高い)
- 自動生成されたスクリプトを実行?(より安全)
マイグレーションならば、開発環境でテスト済みの変更を本番環境に正確に適用できます。
4. 変更履歴として機能する
マイグレーションファイルはデータベースの変更履歴となります。
- いつ、どのフィールドが追加されたか
- リレーションはどう変化したか
- データ構造に関する意思決定の記録
こうした記録は、長期プロジェクトでは非常に価値があります。
5. ロールバックが可能
何か問題が発生した場合、特定のマイグレーションまで戻すことができます。
まずは、マイグレートファイルの履歴を確認して、自分がどの時点に戻りたいか?を確認します。
python manage.py showmigrations
特定のデータベースの状態に戻すには以下のコマンドを実行しましょう。
#基本構文
python manage.py migrate <アプリ名> <マイグレーション名>
#例えばの書き方
python manage.py migrate app_name 0003_previous_migration

このコマンドで、指定したマイグレーションの状態にデータベースを戻せます。
実践的な視点
マイグレーションがなかったら、[ SQL文を手動で作成 ] ⇨ [ テスト ] ⇨ [ 本番 ] ⇨ [何かしらで履歴管理(忘れがち) ] になるところを、Djangoのマイグレーションは、これらのステップをほとんど自動化します。
- モデルを変更
- makemigrationsでマイグレーションファイルを生成
- migrateでデータベースに変更を適用
- マイグレーションファイルをバージョン管理システムにコミット

ここまででもお腹いっぱいだと思うのですが、以下の項目ではマイグレーションを行うときの注意点を記載します。
実際に手を動かして開発する時に、「ふぅん」って思えれば十分だと思いますが、お目通しいただければ幸いです。
マイグレーションをするときの注意事項
1. 頻繁にマイグレーションを作成する
モデルに変更を加えたら、すぐにマイグレーションを作成・適用することをお勧めします。理由は主に以下の3つです。
- 変更内容が明確にトラッキングできる
- 問題が発生した場合に切り分けやすい
- チーム開発において他のメンバーとの衝突を減らせる
2. マイグレーションは小さく保つ
大きな変更を一度に行うのではなく、小さな変更を段階的に行いましょう。例えば、以下のような変更を一度に行うのは避けたほうが良いです。
- 複数のモデルの追加
- フィールドの追加と削除
- リレーションの変更
代わりに、これらの変更を個別のマイグレーションに分けることで、各ステップでの問題を特定しやすくなります。
3. マイグレーション適用前にテストする
本番環境に適用する前に、開発環境やステージング環境でマイグレーションをテストしましょう。
特に大きなデータセットに対する変更や、リレーションの変更など、複雑なマイグレーションでは重要です。
# マイグレーションのSQL確認(実行はしない)
python manage.py sqlmigrate app_name migration_number
4. マイグレーションファイルのバージョン管理
マイグレーションファイルは必ずバージョン管理システム(GitなどのVCS)に含めてください。
チームの他のメンバーがあなたのモデル変更を適用できるようにするために重要です。
5. 削除系操作に注意する
フィールドの削除や型の変更など、データ損失につながる可能性がある変更には特に注意が必要です。
可能な限り、このような変更は段階的に行いましょう。
- 新しいフィールドを追加
- データを古いフィールドから新しいフィールドにコピー
- コードを更新して新しいフィールドを使用
- 古いフィールドを削除
6. マイグレーション履歴の管理
プロジェクトが進むにつれてマイグレーションファイルが増えていきます。
開発の節目では、マイグレーションをスクワッシュ(統合)して履歴を整理することも検討しましょう。
python manage.py squashmigrations app_name start_migration_number end_migration_number
#start_migration_number : 統合したいマイグレーションファイルの最初のファイル
#end_migration_number : 統合したいマイグレーションファイルの最後のファイル
ただし、本番環境にデプロイ済みのマイグレーションはスクワッシュしないよう注意してください。
まとめ
適切なマイグレーション管理を行って、堅牢なデータベースの作成を心がけましょう。
頻繁に小さなマイグレーションを作成・適用し、データマイグレーションを活用することで、モデル変更によるリスクを最小限に抑えつつ、アプリケーションを進化させることができます。
特に重要なポイントを再掲します。
- 変更後すぐにマイグレーションを作成する
- マイグレーションは小さく保つ
- 適用前にテスト環境で確認する
- データマイグレーションを活用して既存データを適切に変換する
これらのベストプラクティスを守ることで、Djangoアプリケーションのデータモデルを効率的かつ安全に変更を加えアプリの機能向上に役立つことでしょう!