DjangoでDBに関連した操作をするとき、django-admin
のmakemigrations
でマイグレーションファイルを作成して、migrate
でマイグレーションを実行します。
そのマイグレーション実行時に実行されるSQLを確認するには、sqlmigrate
を利用します。
Django4.2で検証しました。
sqlmigrate
https://docs.djangoproject.com/ja/4.2/ref/django-admin/#sqlmigrate
コマンドは以下のようになっています。
django-admin sqlmigrate app_label migration_name
app_label
はアプリケーション名、
migration_name
はマイグレーションファイルの名前です。
例えば、task
テーブルをrenameする次のようなマイグレーションファイル0008_alter_task_table.py
が生成されたとします。
# Generated by Django 4.2.9 on 2024-03-28 11:25 from django.db import migrations class Migration(migrations.Migration): dependencies = [ ("tasks", "0007_taskbackup"), ] operations = [ migrations.AlterModelTable( name="task", table="task_rename", ), ]
その時、コマンドは以下のようになります。
django-admin sqlmigrate tasks 0008_alter_task_table
実行結果(SQLite3の場合)は次のような結果が返されます。
BEGIN; -- -- Rename table for task to task_rename -- ALTER TABLE "task" RENAME TO "task_rename"; COMMIT;
マイグレーションファイルについて
今回の例のマイグレーションファイル 0008_alter_task_table.py
で内部で AlterModelTable
が利用されています。
DBスキーマ操作用のクラスが定義されており、リファレンスで言うと以下のようなページがあります。
https://docs.djangoproject.com/ja/4.2/ref/migration-operations/#altermodeltable
定義しているモデルのテーブル名を変更します(Meta サブクラスの db_table オプションを参照します)。
と記述されており、大まかなレベルではリファレンスからどういうことをするか確認できます。
詳細に確認するには、sqlmigrate
を実行したら良いんだな、という理解をしています。
SQLの定義場所
そして、SQLは以下に定義されています。
https://github.com/django/django/blob/main/django/db/backends/base/schema.py#L75
ここではこの変数をベースにSQLが発行されていたことが確認できます。
sql_rename_table = "ALTER TABLE %(old_table)s RENAME TO %(new_table)s"
また、今回はSQLite3
の場合でしたが、MySQL
PostgreSQL
で実行できないSQLもあるので、それを吸収できるよう、それぞれのDBに合わせたディレクトリとファイル(及び変数)が存在します。
DBをMySQLに置き換えると、以下のようになります。
-- -- Rename table for task to task_rename -- RENAME TABLE `task` TO `task_rename`;
コードは以下です。
https://github.com/django/django/blob/main/django/db/backends/mysql/schema.py#L7
sql_rename_table = "RENAME TABLE %(old_table)s TO %(new_table)s"
余談
何回か取り上げたSQLを確認しよう、というシリーズの延長線上になりましたが、Django任せにせず、どういう風にDBを操作しているかを確認するのも大事だなと思いました。
Djangoのマイグレーションファイルも「Djangoがよしなに生成してくれるもの」くらいの認識でいましたが、マイグレーション用のクラスがあったことや、その裏側でSQLも定義されていることを改めて認識できて、世界が広がって面白いなぁと思いました。