1/99スタックエンジニアの適当記録

適当なことを書きます。関西で転職したいです。

djangoのmigrate、migrationについて

migrateについての理解がないので調べがてらまとめていきます。

migrateとは

migrateは英語では「移住する、移行する、移動する、渡る」の意です。
ちなみによく聞く、migrationは、その名詞なので「移住、渡り、転生」などの意です。

webのmigrate、migrationとは

webで言われるマイグレーションとは、一般的には「データの移行」です。
データはデータベースで扱われるため、データベースの内容を変更する際に、
マイグレーション処理や、マイグレートが行われます。
マイグレーション機能の例だと、Ruby on RailsDjangocakePHPなどがあります。

dojangoのmigrate

djangoでは1.7からマイグレーション機構が標準で搭載されるようになりました。
djangoマイグレーションはモデルを利用し、自動生成するコードを実行することで、データを作成したり変更したりします。

仕組みの部分ですが、まず状態として3つあります。
モデル(models.py)、マイグレーションファイル(*.py)、データベース

また、これらに関連する最低限のコマンドとして2つmakemigrations、migrateの2つを扱います。

イメージしやすいように、エクセルで簡単な図を書いてみました。

f:id:roku28632:20191219194615p:plain

イメージがついたでしょうか?

djangoでmigrate

では、実際にdjangoでmigrateとmakemigrationsをやってみます。

先に紹介しておきますが、下記はdajnagoチュートリアルを参考にしています。
docs.djangoproject.com


まず、makemigrationです。

事前に最低限の構成である、プロジェクトとアプリを作ります。

C:\work\django_practice\test>django-admin startproject testtest

C:\work\django_practice\test\testtest>python manage.py startapp testaaa

作成はこれだけです。

作ったアプリをプロジェクトに認識させます。

プロジェクトを作成した段階で作成されるプロジェクトの設定ファイル、settings.pyのINSTALLED_APPSにコードを追加します。

# Application definition

INSTALLED_APPS = [
    'testsuruyo.apps.TestsuruyoConfig',
    'testaaa.apps.TestaaaConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

こんな感じです。

補足としては、アプリを作った段階で、apps.pyにTestaaaConfigが定義されています。
なので、testsuruyoフォルダのappsファイルのTestaaaConfigメソッドを指定しているということです。

続いて、データベースのレイアウトを定義するモデルを作成します。

migrateするということは、データベースに対して変更したい内容があるということです。
上記で書いたように、dajngoはモデルを使ってデータベースを変更します。

では、モデルの内容です。
今までの流れでいくと、モデルは下記にあります。

C:\work\django_practice\test\testtest\testsuruyo>notepad models.py

追加したコードです。

from django.db import models


class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')


class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

では、準備が整ったので、makemigrationsしてみます。

C:\work\django_practice\test\testtest>python manage.py makemigrations testaaa
Migrations for 'testaaa':
  testaaa\migrations\0001_initial.py
    - Create model Question
    - Create model Choice

このコマンドによってマイグレーションファイルが作成されました。
実際に見てみます。

C:\work\django_practice\test\testtest\testaaa\migrations
0001_initial.py

ありました。

このあとは、マイグレーションファイルに対してmigrateコマンドを実行して、DBに更新を加えていきます。

djangoにはマイグレーションファイルの内容を確認するためのコマンドが用意されています。
念の為migrateによって、何が実行されるか、事前に確認してみましょう。

実行するコマンドは、sqlmigrate です。

C:\work\django_practice\test\testtest>python manage.py sqlmigrate testaaa 0001
BEGIN;
--
-- Create model Question
--
CREATE TABLE "testaaa_question" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "question_text" varchar(200) NOT NULL, "pub_date" datetime NOT NULL);
--
-- Create model Choice
--
CREATE TABLE "testaaa_choice" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "choice_text" varchar(200) NOT NULL, "votes" integer NOT NULL, "question_id" integer NOT NULL REFERENCES "testaaa_question" ("id") DEFERRABLE INITIALLY DEFERRED);
CREATE INDEX "testaaa_choice_question_id_37cb4ff6" ON "testaaa_choice" ("question_id");
COMMIT;

もし、SQLが理解できる人であれば、何が行われているかこれで理解できるでしょう。
ちなみに、今回はテーブルを作成しています。
問題がなさそうであれば、migrateして、上記のSQLを実行してみます。

C:\work\django_practice\test\testtest>python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions, testaaa
Running migrations:
  Applying testaaa.0001_initial... OK

migrateコマンドは、すべての適用されていないマイグレーションを補足して、DBに対して実行します。
これでデータベースを更新することができました。

やったことです。
・モデルを変更する (models.py の中の)
・これらの変更のためのマイグレーションを作成するために python manage.py makemigrations を実行します。
・データベースにこれらの変更を適用するために python manage.py migrate を実行します。

最後に

migrateをまとめて実行してみました。
最低限の知識はこれで理解できるようになったかなと思います。
以上です