Opened 9 years ago
Last modified 9 years ago
#27297 closed Bug
infinite AlterField migrations created for foreign key after case-only model name change — at Version 5
| 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 he first place.
Change History (5)
comment:1 by , 9 years ago
| Cc: | added |
|---|---|
| Description: | modified (diff) |
comment:2 by , 9 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 , 9 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 , 9 years ago
Replying to Baptiste Mispelon:
Is it possible you changed the name of
Model1in 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 , 9 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.
I tested with several other versions and got the following weirdly unpredictable behaviour:
(django_1.7) $ for _ in {{1..10}}; do ./manage.py makemigrations; done Migrations for 'app1': 0003_auto_20160929_2012.py: - Alter field fk_to_model1 on model2 Migrations for 'app1': 0004_auto_20160929_2012.py: - Alter field fk_to_model1 on model2 Migrations for 'app1': 0005_auto_20160929_2012.py: - Alter field fk_to_model1 on model2 Migrations for 'app1': 0006_auto_20160929_2012.py: - Alter field fk_to_model1 on model2 Migrations for 'app1': 0007_auto_20160929_2012.py: - Alter field fk_to_model1 on model2 No changes detected Migrations for 'app1': 0008_auto_20160929_2012.py: - Alter field fk_to_model1 on model2 Migrations for 'app1': 0009_auto_20160929_2012.py: - Alter field fk_to_model1 on model2 No changes detected No changes detected(django_1.8)$ for _ in {{1..20}}; do ./manage.py makemigrations; done No changes detected No changes detected Migrations for 'app1': 0003_auto_20160929_1957.py: - Alter field fk_to_model1 on model2 Migrations for 'app1': 0004_auto_20160929_1957.py: - Alter field fk_to_model1 on model2 No changes detected Migrations for 'app1': 0005_auto_20160929_1957.py: - Alter field fk_to_model1 on model2 No changes detected No changes detected Migrations for 'app1': 0006_auto_20160929_1957.py: - Alter field fk_to_model1 on model2 Migrations for 'app1': 0007_auto_20160929_1957.py: - Alter field fk_to_model1 on model2 Migrations for 'app1': 0008_auto_20160929_1957.py: - Alter field fk_to_model1 on model2 No changes detected Migrations for 'app1': 0009_auto_20160929_1957.py: - Alter field fk_to_model1 on model2 No changes detected No changes detected No changes detected Migrations for 'app1': 0010_auto_20160929_1957.py: - Alter field fk_to_model1 on model2 No changes detected No changes detected Migrations for 'app1': 0011_auto_20160929_1957.py: - Alter field fk_to_model1 on model2(django_1.9)$ for _ in {{1..10}}; do ./manage.py makemigrations; done Migrations for 'app1': 0003_auto_20160929_2010.py: - Alter field fk_to_model1 on model2 Migrations for 'app1': 0004_auto_20160929_2010.py: - Alter field fk_to_model1 on model2 Migrations for 'app1': 0005_auto_20160929_2010.py: - Alter field fk_to_model1 on model2 Migrations for 'app1': 0006_auto_20160929_2010.py: - Alter field fk_to_model1 on model2 Migrations for 'app1': 0007_auto_20160929_2010.py: - Alter field fk_to_model1 on model2 Migrations for 'app1': 0008_auto_20160929_2010.py: - Alter field fk_to_model1 on model2 Migrations for 'app1': 0009_auto_20160929_2010.py: - Alter field fk_to_model1 on model2 Migrations for 'app1': 0010_auto_20160929_2010.py: - Alter field fk_to_model1 on model2 Migrations for 'app1': 0011_auto_20160929_2010.py: - Alter field fk_to_model1 on model2 Migrations for 'app1': 0012_auto_20160929_2010.py: - Alter field fk_to_model1 on model2