こんにちは、かつコーチです。
ここからは「データベース・ORM」編に入ります。
Djangoでモデルを定義しても、それだけではデータベースに変化は起きません。
makemigrationsとmigrateという2つのコマンドを実行して、初めてデータベースにテーブルが作られます。
今回はこの2つのコマンドの役割と、実務でよくあるつまずきを解説します。
モデルとデータベースをつなぐ「マイグレーション」
マイグレーションとは
マイグレーションとは、モデル(Pythonのクラス)の定義とデータベースの実際の構造(テーブル)を同期させるための仕組みです。
Djangoでは、モデルを直接SQLで管理するのではなく、Pythonのコードとして定義したモデルをもとに、Djangoが自動でSQLを生成してくれます。
この「モデルの変更履歴」を記録したファイルが、マイグレーションファイルです。
なぜ2段階のコマンドに分かれているのか
「モデルを変更したら即座にDBに反映すればいいのでは?」と思うかもしれません。
しかし、Djangoはmakemigrations(変更内容の記録)とmigrate(実際の反映)の2段階に分けています。
理由は、変更内容を一度ファイルとして残すことで、チーム開発でのレビューやバージョン管理(Git)に載せられるようにするためです。
マイグレーションファイルはGitでコミットする対象であり、「いつ・誰が・どんな変更をDBに加えたか」の履歴になります。
makemigrationsコマンドの使い方
モデルを定義してマイグレーションファイルを作る
まず、モデルを定義します。
# blog/models.py
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
モデルを定義したら、次のコマンドを実行します。
python manage.py makemigrations
実行すると、アプリのmigrations/フォルダに0001_initial.pyのようなファイルが生成されます。
blog/migrations/0001_initial.py
- Create model Post
このファイルには、「Postという名前でテーブルを作り、title・content・created_atという列を用意する」という指示がPythonのコードとして記録されています。
中身を確認する習慣をつける
生成されたマイグレーションファイルは、makemigrationsが自動生成したコードとはいえ、必ず一度は目を通す習慣をつけましょう。
意図しないフィールドの削除や型変更が含まれていないかを確認できるからです。
migrateコマンドの使い方
マイグレーションファイルをDBに反映する
makemigrationsはあくまで「変更内容をファイルに記録する」だけで、実際のデータベースはまだ変わっていません。
DBに反映するには、次のコマンドを実行します。
python manage.py migrate
これで、0001_initial.pyの内容にもとづいてテーブルが作成されます。
現在の適用状況を確認する
どのマイグレーションが適用済みかを確認したいときは、showmigrationsコマンドが便利です。
python manage.py showmigrations
blog
[X] 0001_initial
[ ] 0002_post_is_published
[X]が適用済み、[ ]が未適用を表しています。
モデル変更のたびにこの2コマンドを繰り返す
フィールド追加の例
モデルにフィールドを追加した場合も、同じ流れで反映します。
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
is_published = models.BooleanField(default=False) # 追加
python manage.py makemigrations
python manage.py migrate
「モデルを変更する → makemigrations → migrate」という3ステップは、Django開発の基本サイクルとして体で覚えておくと迷いません。
つまずきやすいポイント
migrateを忘れたままアプリを動かしてエラーになる
❌ Before:makemigrationsだけ実行してmigrateを忘れる
python manage.py makemigrations
python manage.py runserver
この状態でアプリにアクセスすると、次のようなエラーが出ます。
django.db.utils.OperationalError: no such column: blog_post.is_published
筆者も新しいフィールドを追加した直後、migrateを実行し忘れたままアプリを起動してこのエラーに遭遇しました。
「コードは正しいはずなのに、なぜか列が存在しないと言われる」という状態で、しばらく原因が分からず時間を溶かしてしまいました。
✅ After:makemigrationsの後、必ずmigrateまで実行する
python manage.py makemigrations
python manage.py migrate
python manage.py runserver
このエラーメッセージが出たときは、まずpython manage.py showmigrationsで未適用のマイグレーションがないか確認するのが最短の解決方法です。
既存フィールドにNOT NULLを追加してエラーになる
すでにデータが入っているテーブルに、デフォルト値のない必須フィールドを追加しようとすると、makemigrations実行時に対話形式で質問されます。
You are trying to add a non-nullable field 'category'...
Please select a fix:
1) Provide a one-off default now
2) Quit and manually define a default value in models.py
既存の行に何を入れるか決まっていない状態なので、Djangoが判断を委ねてくるわけです。
多くの場合、モデル側にdefault=""のような初期値を設定してからmakemigrationsをやり直す方が、後から履歴を追いやすくなります。
まとめ
この記事のポイント
makemigrationsはモデルの変更内容をファイルとして記録するコマンドmigrateはそのファイルをもとに実際のDBへ反映するコマンド- モデルを変更したら「makemigrations → migrate」を必ずセットで実行する
showmigrationsで適用状況を確認できる- 既存データがあるテーブルへの必須フィールド追加は、デフォルト値の指定に注意する
次に読むべき記事
- モデルの基本:フィールドタイプとCRUD操作
- ForeignKey・ManyToManyでリレーションを組む
- makemigrationsが競合して困った話と対処法
タグ: Django, 初心者向け, データベース