環境
$ python -V
Python 3.9.1
$ python -m django --version
3.1.5
起こった問題
こういうマイグレーションがあるとします。
$ python manage.py showmigrations
user
[X] 0001_initial
[X] 0002_user_name
[X] 0003_auto_20220214_1200
squashmigrations
を使って0002と0003をまとめます。
このとき、--squashed-name
オプションでまとめた後のファイル名を指定します。
$ python manage.py squashmigrations user 0002 0003 --squashed-name user_name
Will squash the following migrations:
- 0002_user_name
- 0003_auto_20220214_1200
Do you wish to proceed? [yN] y
Optimizing...
No optimizations possible.
Created new squashed migration /app/user/migrations/0002_user_name.py
You should commit this migration but leave the old ones in place;
the new migration will be used for new installs. Once you are sure
all instances of the codebase have applied the migrations you squashed,
you can delete them.
この後、showmigrations
でマイグレーションを確認してみると、なんとuser
アプリのマイグレーションが全て消えてしまっています。
$ python manage.py showmigrations
user
(no migrations)
migrate
してみても、何も適用されません。--fake
をつけても同様。
原因
消えてしまったマイグレーションは、単にDjangoから認識されなくなったというだけで、ファイル自体は残っています。
squash後のファイルの中身を見てみましょう。
# Generated by Django 3.1.5 on 2022-02-14 06:56
from django.db import migrations, models
class Migration(migrations.Migration):
replaces = [('user', '0002_user_name'), ('user', '0003_auto_20220214_1200')]
dependencies = [
('user', '0001_initial'),
]
operations = [
# 割愛
]
squashmigrations
で作られたマイグレーションには、replace
属性が追加されます。
この属性で、どのマイグレーションをまとめて作られたのかがわかるようになっていて、このリストにあるマイグレーションは無視されます。
ここが今回の問題の原因です。
replaces
に含まれるマイグレーションと自分の名前が同じなので(自分を無視する?)、依存関係がぐちゃぐちゃになってしまったようです。
こう直す
replaces
属性を削除することで解消しました。
その場合、残った0003_auto_20220214_1200.py
が実行されるようになるので、こちらも削除しておくこと。
参考
マイグレーション | Django ドキュメント | Django
Django マイグレーション完全に理解した (基礎編) 🍏 - くろのて