環境
$ 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 マイグレーション完全に理解した (基礎編) 🍏 - くろのて