【Django】makemigrations/migrateの基本:モデルをDBに反映する

Django

こんにちは、かつコーチです。

ここからは「データベース・ORM」編に入ります。

Djangoでモデルを定義しても、それだけではデータベースに変化は起きません。

makemigrationsmigrateという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という名前でテーブルを作り、titlecontentcreated_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, 初心者向け, データベース

タイトルとURLをコピーしました