DjangoでApp単位のMigrationをRollbackについてまとめてみる
環境
- Django: 2.2 ( 3.0 )
↓ 取り敢えず、MigrationとかAppについて振り返ってみます。
DjangoにおけるAppとは
Djangoを使っていると App
という概念で プロジェクト内に複数のアプリケーションを作って開発をしていくと思います。 そもそも、Djangoにおけるアプリケーションってなんなのよ?という話ですが、公式では プロジェクトとアプリケーションは 完全に親子関係である、みたいな感じで言及されています。
プロジェクトとアプリケーション
プロジェクトとアプリの違いは何でしょうか? アプリとは、ウェブログシステム、公的記録のデータベース、小規模な投票アプリなど、何かを行う Web アプリケーションです。プロジェクトは、特定のウェブサイトの構成とアプリのコレクションです。プロジェクトには複数のアプリを含めることができます。 アプリは複数のプロジェクトに存在できます
例えば user
というアプリケーションを作る場合は 以下のような階層構造のディレクトリを切って( python manage.py startapp user
とすれば自動的に )開発を進めます。
user/
__init__.py
admin.py
apps.py
migrations/
__init__.py
models.py
tests.py
views.py
アプリケーションに関連するDB(テーブル)を扱うのであれば、上記ディレクトリの中の models.py
に Model を実装し、python manage.py makemigrations user
などとコマンドを叩くと、Migration ファイルを作成することができます。
Migrationについて
作成
Migrationは ディレクトリの migrations/
ディレクトリの中に作成されていきます。
初回のMigrationは 一般的に 0001_initial.py
などの名前で作成され、以降は {0001からインクリメント}_{マイグレーションの内容}.py
という形式で作られます。
例えば、0001_initial.py
を作成後に member
テーブルだけを作る Migrationを作って python manage.py makemigrations user
を叩くことで 0002_member.py
というファイルをDjangoが作ってくれます。
member
というファイル名についてですが、これはDjangoが自動的に定義してくれます。 複数のModelの定義の変更を一つのMigrationに入れると 0002_auto_20200930_1200
みたいな感じで 年月日_日時 でファイル名を作成しますが、 新しいテーブルを1個追加する等であれば、ファイル名にその追加されるテーブル名を含めてくれたりします。
かしこいですね。
適用
python manage.py migrate user 0001
とすることで データベースの状態を0001_***.py
まで実行された状態にしてくれます。
想像しやすいとは思いますが、後ろを 0010
とするとで migrations/ ディレクトリ内の 0001 〜0010 までのMigrationファイルが適用された状態になります。
ちなみに後ろの数字を除いて python manage.py migrate user
とすると、 最新のMigrationが適用された状態にしてくれます。
ちなみに、このどこまで実行されているのか、みたいなのは Djangoが接続しているデータベースの中に管理するテーブルがあってそこで管理されてたりします。
ロールバック
では、 ロールバックは どうするのでしょうか。 実は Djangoには python manage.py rollback 〜
みたいなコマンドはありません。 ここでも migrate
を使います。
django-admin と manage.py | Django ドキュメント | Django
公式サイトではこう記述されています。
Brings the database schema to a state where the named migration is applied, but no later migrations in the same app are applied.
和訳すると ...
データベース スキーマを、指定されたマイグレーションが適用され、同じアプリ内のそれ以降のマイグレーションは適用されない状態にします。
ということです。
例えば、0010 まで適用された状態から一個ロールバックしたい場合は python manage.py migrate user 0009
と 一個前の状態を指定すると、 Djangoは 「データベースを 0009 のMigrationまで適用された状態にして それ以降(つまり 0010 )のMigrationが適用されていない状態」 に変えてくれます。これが実質ロールバックになるわけです。
では、 0001
をロールバックするにはどうすれば良いのでしょうか?という話があります。 0001_initial.py
は user の中で最初のMigrationファイルであり、 「それより前のもの」 はありません。
その場合は python manage.py migrate user zero
と zero
というキーワードをつけることで user アプリケーションのMigration を全く適用されてない状態にすることができます。
まとめ
コマンド | 効果 |
---|---|
python manage.py user 0001 |
0001までMigrationを適用し、0002以降は適用していない状態にする |
python manage.py user |
user アプリケーションのMigrationを最新まで全て適用する状態にする |
python manage.py user zero |
user アプリケーションのMigrationを何も適用されていない状態にする |
Discussion