はじめに
Djangoを使っていて気になることがありませんか、、?
models.py
に編集を加えた後、makemigrations
やmigrate
を実行しませんでしたか?
僕がはじめてDjangoを触った時は、脳死でこのコマンドを実行していました。
webアプリ開発でDjangoを使うようになってから半年ほどたち、このコマンドが何をしているのか、
少しずつ理解できてきたので、備忘録として記事に残したいと思います。
この記事が参考になりそうな人
- 最近Djangoを使い始めて、慣れてきた人
-
makemigrations
やmigrate
について理解したい人
前知識
###マイグレーションについて
- Django公式ドキュメントでは以下のように説明されています
Migrations are Django’s way of propagating changes you make to your models (adding a field, deleting a model, etc.) into your database schema. They’re designed to be mostly automatic, but you’ll need to know when to make migrations, when to run them, and the common problems you might run into.
- DeepLでの翻訳
移行とは、モデルに加えた変更 (フィールドの追加やモデルの削除など) をデータベーススキーマに反映させるための Django の方法です。ほとんど自動で行われるように設計されていますが、いつ移行を行うのか、いつ実行するのか、そしてよくある問題について知っておく必要があります。
つまり、マイグレーションとは
- データベースに変更を加えるための仕組み
-
models.py
に対して行った変更をデータベーススキーマに反映させる仕組み - データベースのバージョン管理システムのようなもの(GitHubを使っている人はこれが一番納得しやすいかも?)
マイグレーションファイルについて
-
models.py
を元に作られるファイル -
models.py
の内容をデータベースに反映させるための中間ファイル - 1番最初の
models.py
の内容と、それを基準にmodels.py
の変更によってできる差分のデータファイル
./manage.py makemigrations
でなにが起きる?
結論から言うとマイグレーションファイルが作成されます。
Person
モデル
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=30)
age = models.IntegerField()
makemigrations
を実行すると
$ ./ manage.py makemigrations
Person
モデルを元にマイグレーションファイルが作成されます
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Person',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=30)),
('age', models.IntegerField()),
],
),
]
今、Person
モデルに対するマイグレーションファイルが存在しなかったので、0001_initial.py
というファイル名でファイルが作成されました。
以後、この0001_initial.py
が元となり、マイグレーションファイルが更新されていきます。
では、ここでPerson
モデルにweight
というフィールドを追加し、もう一度makemigrations
を実行してみます
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=30)
age = models.IntegerField()
weight = models.IntegerField()
$ ./ manage.py makemigrations
from django.db import migrations, models
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('sample_app', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='person',
name='weight',
field=models.IntegerField(default=django.utils.timezone.now),
preserve_default=False,
),
]
すると、0001_init.py
に依存した、0002_person_weight.py
が新規作成されます。
この
0002_person_weight.py
には、0001_init.py
との差分が記録されているイメージです。
つまり、makemigrations
を実行すると、モデルに変更があれば、その変更をファイルに残します。
しかし、makemigrations
を実行しただけではデータベースには反映されません。
./manage.py migrate
でなにが起きる?
makemigrations
によってできたマイグレーションファイルをデータベースに反映させます。
マイグレーションファイルに従って、データベースに変更を加えるイメージです。
./manage.py migrate アプリ名 マイグレーション名
で特定のマイグレーションファイルを反映させることができます。
アプリ名とマイグレーション名を省略した場合は、未適用のマイグレーションファイルを全てデータベースに反映させます。
./manage.py migrate
これだと未適用のマイグレーションファイルが全てデータベースに反映させます。
さいごに
記事の内容や書き方にまだまだ改善できる点が多いと思いますが、書きながら覚えて改善していきたいと思います!
記事書いてて楽しかったので、これから定期的に投稿していこうとかな思います