モデルを定義して makemigrations と migrate する

Django でデータベースを扱うには、Python のクラスとしてモデルを定義し、マイグレーションという仕組みを通じてテーブルを作成します。SQL を直接書く必要はありません。

モデルの定義

モデルは models.py に記述します。django.db.models.Model を継承したクラスが 1 つのテーブルに対応し、クラス属性がカラムになります。

from django.db import models

class Article(models.Model):
    title = models.CharField(max_length=200)
    body = models.TextField()
    published_at = models.DateTimeField(auto_now_add=True)
    is_draft = models.BooleanField(default=True)

この例では Article というテーブルが作られ、titlebodypublished_atis_draft の 4 つのカラムが定義されます。id フィールドは Django が自動的に追加するため、明示的に書く必要はありません。

よく使うフィールド型を整理しておきましょう。

フィールド型用途備考
CharField短い文字列max_length 必須
TextField長い文字列max_length 不要
フィールド型用途備考
IntegerField整数-2147483648〜2147483647
BooleanField真偽値True / False
DateTimeField日時auto_now / auto_now_add

auto_now_add=True はレコード作成時に自動で現在時刻を設定し、auto_now=True は保存するたびに現在時刻で上書きします。作成日時と更新日時を分けたい場合は、両方を定義するのが一般的です。

class Article(models.Model):
    title = models.CharField(max_length=200)
    body = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

makemigrations でマイグレーションファイルを生成する

モデルを定義・変更したら、まず makemigrations を実行します。このコマンドはモデルの変更内容を検出し、マイグレーションファイルとして記録します。

python manage.py makemigrations

実行すると、migrations/ ディレクトリに 0001_initial.py のようなファイルが生成されます。このファイルには「どんなテーブルを作るか」「どのカラムを追加・変更するか」といった情報が Python コードで記述されています。

models.py を編集する

makemigrations でマイグレーションファイル生成

migrate でデータベースに反映

マイグレーションファイルはバージョン管理の対象です。チーム開発では Git にコミットし、メンバー間でデータベースの変更履歴を共有します。

migrate でデータベースに反映する

マイグレーションファイルを作っただけでは、データベースにはまだ反映されていません。実際にテーブルを作成・変更するには migrate を実行します。

python manage.py migrate

Django は未適用のマイグレーションを順番に実行し、データベースのスキーマを更新します。どのマイグレーションが適用済みかは django_migrations テーブルで管理されているため、同じマイグレーションが二重に適用されることはありません。

マイグレーションの状態を確認する

現在のマイグレーション状況を確認するには showmigrations コマンドを使います。

python manage.py showmigrations

[X] が付いているものは適用済み、[ ] は未適用を示します。特定のアプリだけ確認したい場合は、アプリ名を引数に渡せます。

makemigrations

モデルの変更を検出してマイグレーションファイルを生成する。データベースには何も起きない

migrate

マイグレーションファイルの内容をデータベースに適用する。テーブルの作成や変更が実際に行われる

フィールドを後から追加する場合

既存のモデルにフィールドを追加すると、既存のレコードにはそのフィールドの値が存在しません。Django は makemigrations 時に「デフォルト値をどうするか」を対話的に尋ねてきます。

class Article(models.Model):
    title = models.CharField(max_length=200)
    body = models.TextField()
    category = models.CharField(max_length=50, default='未分類')

default を指定しておけば、対話プロンプトなしでマイグレーションファイルが生成されます。null=True を設定して NULL を許容する方法もありますが、文字列フィールドでは default='' の方が Django の慣習に沿っています。

マイグレーションはデータベースの変更履歴そのものです。安易に削除や編集をせず、変更があるたびに makemigrationsmigrate のサイクルを回すことが、安全なデータベース管理の基本になります。