マイグレーションの実行前後ではshowmigrationsを実行しよう

Djangoマイグレーションの実行状態を確認する方法として、showmigrationsがあります。

https://docs.djangoproject.com/ja/5.0/ref/django-admin/#showmigrations

コマンドは以下のように実行します。

python manage.py showmigrations

以下のように実行されているかどうか、(あるいはマイグレーションファイルが無いこと)が出力されます。

コードはこちらのリポジトリを基にしています(2024/04/06現在のコードに対して、適当にモデルを変更するよう書き加えました)。

https://github.com/nibuno/djangoTaskApp

accounts
 (no migrations)
admin
 [X] 0001_initial
 [X] 0002_logentry_remove_auto_add
 [X] 0003_logentry_add_action_flag_choices
auth
 [X] 0001_initial
 [X] 0002_alter_permission_name_max_length
 [X] 0003_alter_user_email_max_length
 [X] 0004_alter_user_username_opts
 [X] 0005_alter_user_last_login_null
 [X] 0006_require_contenttypes_0002
 [X] 0007_alter_validators_add_error_messages
 [X] 0008_alter_user_username_max_length
 [X] 0009_alter_user_last_name_max_length
 [X] 0010_alter_group_name_max_length
 [X] 0011_update_proxy_permissions
 [X] 0012_alter_user_first_name_max_length
contenttypes
 [X] 0001_initial
 [X] 0002_remove_content_type_name
sessions
 [X] 0001_initial
tasks
 [X] 0001_initial
 [X] 0002_task_title_alter_task_content
 [X] 0003_task_limit_date
 [X] 0004_task_status
 [X] 0005_task_order
 [X] 0006_alter_task_status
 [ ] 0007_alter_task_table

このコマンドを実行することで、マイグレーション適用の状態を確認することができます。

引数まわり

python manage.py showmigrations tasks のようにアプリケーションを指定することで、特定のアプリケーションのマイグレーション状態を確認できます。おそらく、指定して確認するケースは結構使うんじゃ無いかなと思います。

tasks
 [X] 0001_initial
 [X] 0002_task_title_alter_task_content
 [X] 0003_task_limit_date
 [X] 0004_task_status
 [X] 0005_task_order
 [X] 0006_alter_task_status
 [ ] 0007_alter_task_table

--list または -l と言う引数がありますが、これはデフォルトで設定されているので挙動としては変わりません。

--plan または -p と言う引数もあります。これは全体を通したマイグレーションの実行計画が確認できるようでした。

python manage.py showmigrations tasks --plan を実行すると、以下のようになります。

[X]  contenttypes.0001_initial
[X]  auth.0001_initial
[X]  tasks.0001_initial
[X]  tasks.0002_task_title_alter_task_content
[X]  tasks.0003_task_limit_date
[X]  tasks.0004_task_status
[X]  tasks.0005_task_order
[X]  tasks.0006_alter_task_status
[ ]  tasks.0007_alter_task_table

どうやら、以下のコードがマイグレーションの最初に呼び出されているようでした。

https://github.com/django/django/blob/main/django/contrib/contenttypes/migrations/0001_initial.py

また、私はリファレンスを読んで初めて存在に気が付きましたが、django-admin に共通する引数として --verbosity と言うものが存在しており、以下のように実行することで、showmigrations (--list) の場合ではマイグレーション時間を確認することができます。

-python manage.py showmigrations tasks --verbosity 2

tasks
 [X] 0001_initial (applied at 2024-02-10 23:32:44)
 [X] 0002_task_title_alter_task_content (applied at 2024-02-10 23:32:44)
 [X] 0003_task_limit_date (applied at 2024-02-10 23:32:44)
 [X] 0004_task_status (applied at 2024-02-10 23:32:44)
 [X] 0005_task_order (applied at 2024-03-07 22:37:52)
 [X] 0006_alter_task_status (applied at 2024-03-09 22:51:47)
 [ ] 0007_alter_task_table

--plan の場合だと、依存するマイグレーションについても知ることができます。

python manage.py showmigrations tasks --plan --verbosity 2

[X]  contenttypes.0001_initial
[X]  auth.0001_initial ... (contenttypes.0001_initial)
[X]  tasks.0001_initial ... (auth.0001_initial)
[X]  tasks.0002_task_title_alter_task_content ... (tasks.0001_initial)
[X]  tasks.0003_task_limit_date ... (tasks.0002_task_title_alter_task_content)
[X]  tasks.0004_task_status ... (tasks.0003_task_limit_date)
[X]  tasks.0005_task_order ... (tasks.0004_task_status)
[X]  tasks.0006_alter_task_status ... (tasks.0005_task_order)
[ ]  tasks.0007_alter_task_table ... (tasks.0006_alter_task_status)

マイグレーションを実行してみる

あとは実際に、マイグレーションを実行して結果を確認します。

マイグレーションコマンド

python manage.py migrate tasks 0007_alter_task_table

showmigrationsコマンド

python manage.py showmigrations tasks --verbosity 2

出力結果

tasks
 [X] 0001_initial (applied at 2024-02-10 23:32:44)
 [X] 0002_task_title_alter_task_content (applied at 2024-02-10 23:32:44)
 [X] 0003_task_limit_date (applied at 2024-02-10 23:32:44)
 [X] 0004_task_status (applied at 2024-02-10 23:32:44)
 [X] 0005_task_order (applied at 2024-03-07 22:37:52)
 [X] 0006_alter_task_status (applied at 2024-03-09 22:51:47)
 [X] 0007_alter_task_table (applied at 2024-04-06 00:27:38)

[] 0007_alter_task_table が実行済みだと言うことがわかります。

また、ロールバックしてみます。

マイグレーションコマンド

python manage.py migrate tasks 0006_alter_task_status

showmigrationsコマンド

python manage.py showmigrations tasks --verbosity 2

出力結果

tasks
 [X] 0001_initial (applied at 2024-02-10 23:32:44)
 [X] 0002_task_title_alter_task_content (applied at 2024-02-10 23:32:44)
 [X] 0003_task_limit_date (applied at 2024-02-10 23:32:44)
 [X] 0004_task_status (applied at 2024-02-10 23:32:44)
 [X] 0005_task_order (applied at 2024-03-07 22:37:52)
 [X] 0006_alter_task_status (applied at 2024-03-09 22:51:47)
 [ ] 0007_alter_task_table

このように、showmigrations を活用することで、マイグレーションが実行されたかどうか、を確認することができます。

自分がマイグレーション実行の有無を確認したときにセットで書いた方が良いよ、と教えてもらったことがきっかけでした。

と言うのは私はマイグレーション実行後にしか利用していなかったので、正確さ・わかりやすさといった観点から教えてもらったためでした。

自分自身、こうした方が良いな〜 と思ったのでこれからは、マイグレーションの実行前後でshowmigrationsを実行していきます。