Opened 8 years ago
Closed 8 years ago
#27297 closed Bug (duplicate)
infinite AlterField migrations created for foreign key after case-only model name change
Reported by: | Daniel Musketa | Owned by: | nobody |
---|---|---|---|
Component: | Migrations | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | daniel.musketa@…, desecho@… | Triage Stage: | Accepted |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
Tested and affected Django versions:
- 1.7
- 1.8
- 1.9
- 1.9.6
- 1.10.1
A case-only rename of a model is not detected. This leads to infinite migrations on a foreign key field that refers to the renamed model.
I created a minimal working example to reproduce this
behaviour: https://github.com/vlt/django_ticket_27297_capitalization
When you run ./manage.py makemigrations
it will create
the following migration over and over again:
Migrations for 'app1': app1/migrations/0003_auto_20161001_2136.py: - Alter field fk_to_model1 on model2
The new file 0003_auto_20161001_2136.py
:
# -*- coding: utf-8 -*- # Generated by Django 1.10.2 on 2016-10-01 21:36 from __future__ import unicode_literals from django.db import migrations, models import django.db.models.deletion class Migration(migrations.Migration): dependencies = [ ('app1', '0002_model2'), ] operations = [ migrations.AlterField( model_name='model2', name='fk_to_model1', field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='app1.moDEl1'), ), ]
I have no idea why the Autodetector in migrations uses lower() in the first place.
Change History (10)
comment:1 by , 8 years ago
Cc: | added |
---|---|
Description: | modified (diff) |
comment:2 by , 8 years ago
Summary: | makemigrations creates the same migration again and again (because it fails to compare uppercase to lowercase model names) → Non-deterministic infinite AlterField migrations created for foreign key |
---|---|
Triage Stage: | Unreviewed → Accepted |
I'm not sure about the cause, but the root issue is that deconstruction is returning non-deterministic results. Sometimes the fields appear equal and sometimes the case differs in the to
field, as you said.
follow-up: 4 comment:3 by , 8 years ago
I think the issue might be caused by the name='model1',
in the initial migration.
When I generate the migrations, I get name='Model1',
(notice the difference in the capitalization of the model).
How did you generate the initial migration?
I noticed that if I start with class model1(models.Model): ...
, create the initial migration, change to class Model1(models.Model): ...
, then makemigrations
won't detect any changes. Is it possible you changed the name of Model1
in the same way?
comment:4 by , 8 years ago
Replying to Baptiste Mispelon:
Is it possible you changed the name of
Model1
in the same way?
Yes, you’re absolutely right. In the actual project there was first
class adress(models.Model)
(sic!), then
class address(models.Model)
and then finally
class Address(models.Model)
.
In the migration files it looks like this:
class Migration(migrations.Migration): initial = True dependencies = [ ] operations = [ migrations.CreateModel( name='adress', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ], ), ]
and then
class Migration(migrations.Migration): dependencies = [ ('app1', '0001_initial'), ] operations = [ migrations.RenameModel( old_name='adress', new_name='address', ), ]
But then no new change is detected. I tested a rename from adress
to Address
which results in a capitalized new_name='Address',
and everything should be fine.
So, the actual problem might be the rename from a lowercase to capfirst model name. This is not detected by makemigrations which seems to compare everything .lower()
’d.
This doesn’t explain though why changes are detected in only some of my for loop makemigrations
runs. ;-)
Propably related to #22608?
comment:5 by , 8 years ago
Description: | modified (diff) |
---|---|
Summary: | Non-deterministic infinite AlterField migrations created for foreign key → infinite AlterField migrations created for foreign key after case-only model name change |
I narrowed down the cause, created a new example and changed the ticket description accordingly.
comment:6 by , 8 years ago
Description: | modified (diff) |
---|
comment:7 by , 8 years ago
Cc: | added |
---|---|
Has patch: | set |
Version: | 1.10 → master |
Added PR 7469 - Ignore case-only model name changes in migration autodetector
comment:9 by , 8 years ago
Has patch: | unset |
---|---|
Patch needs improvement: | unset |
My patch used an incorrect approach. Need a new patch.
I tested with several other versions and got the following weirdly unpredictable behaviour: