課題
python manage.py migrate
を実行したところ、表題のエラーが発生しました。
django.db.utils.OperationalError: table "t" already existsが出てmigrateできない
・エラー発生なし
python manage.py makemigrations
・エラー発生あり
python manage.py migrate
背景
DB(model)とmigrationFilesは以下のようなになっていた。
(テーブルの例として、食べ物の名前テーブルを使用)
データベース(models.py
)
-
作成済テーブル
Apple
Banana
-
未作成テーブル
Chocolate
migrationの最新ファイル(000X_auto_20XXXXXX.py
)
-
AlterField
(作成する旨の記述なし)Apple
-
CreateModel
(作成する旨の記述あり)-
Banana
←あれ、作成済テーブルのはずだが Chocolate
-
( 略 )
migrations.CreateModel(
name='Banana',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=1000)),
],
),
migrations.CreateModel(
name='Chocolate',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=1000)),
],
),
migrations.AlterField(
model_name='Apple',
name='id',
field=models.UUIDField(default=uuid.UUID('13a6d974-aeba-4faf-b501-fad036c92a0e'), primary_key=True, serialize=False),
)
( 略 )
python manage.py migrate
するが、table already exists
のエラーが発生した。
原因
Chocolate
だけ作成したいのに、Banana
も作成することになっている。
DB内にはBanana
が既に存在するので、already exists
エラーで落ちてしまう。
そのため、migrate
できない。
Modelで履歴と実データに差異が出ている状況だった。
対処法
CreateModelの記述を前回の000X_auto_20XXXXXX.py
に移動することで対処。
前回のmigrationファイルは適応済みの判定であるため、参照されない。
( 略 )
# BananaのCreateModelは前回の'000X_auto_20XXXXXX.py'ファイルに移動
migrations.CreateModel(
name='Chocolate',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=1000)),
],
),
migrations.AlterField(
model_name='Apple',
name='id',
field=models.UUIDField(default=uuid.UUID('13a6d974-aeba-4faf-b501-fad036c92a0e'), primary_key=True, serialize=False),
)
( 略 )
000X_auto_20XXXXXX.py
の中身を書き換えるという発想がなかった。
普段自動でやってくれるので、手動で書き換えるとは思わなかった。
なぜこのような不整合が起こってしまったのかは謎。