[Django] #27297: makemigrations creates the same migration again and again (because it fails to compare uppercase to lowercase model names)

111 views
Skip to first unread message

Django

unread,
Sep 29, 2016, 10:23:56 AM9/29/16
to django-...@googlegroups.com
#27297: makemigrations creates the same migration again and again (because it fails
to compare uppercase to lowercase model names)
--------------------------------+--------------------
Reporter: Daniel Musketa | Owner: nobody
Type: Bug | Status: new
Component: Migrations | Version: 1.10
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Easy pickings: 0 | UI/UX: 0
--------------------------------+--------------------
Tested and affected Django versions:
- 1.9.6
- 1.10.1

I created a minimal working example to reproduce this
behaviour: https://github.com/vlt/migrations

When you run {{{./manage.py makemigrations}}} it will create
the following migration over and over again:

{{{
Migrations for 'app1':
0003_auto_20160929_1358.py:
- Alter field fk_to_model1 on model2
}}}

The new file {{{0003_auto_20160929_1358.py}}}:

{{{
# -*- coding: utf-8 -*-
# Generated by Django 1.10.1 on 2016-09-29 13:58
from __future__ import unicode_literals

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('app1', '0002_add_model2'),
]

operations = [
migrations.AlterField(
model_name='model2',
name='fk_to_model1',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
to='app1.Model1'),
),
]
}}}

The #django conversation that led to this ticket:

{{{
11:20:01 vlt | Another question: What stupid thing │
| could I have done that causes │
| makemigrations (v 1.9.6 and 1.10.1) │
| to create the very same AlterField() │
| migration over and over again │
| everytime I run that command? (I’ll │
| try to create an MWE.) │
11:22:10 vlt | $ for _ in {{1..10}}; do ./manage.py │
| makemigrations; done │
11:22:24 vlt | That will produce 10 new migrations │
| files. All looking the same. │
11:22:28 vlt | :-D │
11:37:46 +bmispelon | vlt: what does the migration look │
| like? │
11:50:56 vlt | This is what every of the previous 25 │
| migrations looks like: │
| https://dpaste.de/wS4z (except for │
| the dependencies, of course) │
11:52:13 +bmispelon | vlt: strange. What does the model │
| look like? │
11:54:44 vlt | bmispelon: https://dpaste.de/rWGf
11:55:21 vlt | bmispelon: Maybe it’s caused by the │
| @property def name() ... weirdness. │
11:58:27 +bmispelon | vlt: I can't reproduce your issue on │
| my machine (I copied the same model │
| you pasted but when I run │
| makemigrations a second time, it │
| doesn't detect new changes) │
11:58:36 +bmispelon | vlt: which version of Python/Django │
| are you using? │
11:59:29 vlt | bmispelon: Created the project on │
| 1.10.1 (3.4), verified the migration │
| zombies also on 1.9.6 (3.4). │
12:00:02 vlt | bmispelon: I tried to reproduce with │
| a smaller model without success. │
12:00:16 vlt | bmispelon: I’ll paste the existing │
| migrations … │
12:01:01 +apollo13 | vlt: name shouldn't affect anything, │
| since it is a normal python variable │
| and not migration related in any way │
12:02:03 +bmispelon | (I still can't reproduce the issue. I │
| tried creating the migration under │
| 1.10 then switching to 1.9 and I │
| still get "no changes detected") │
12:09:44 vlt | bmispelon, apollo13: │
| http://77up.space/migrations.tar
12:31:30 vlt | bmispelon: Can you reproduce the │
| migration behaviour using the │
| migrations.tar I uploaded? │
12:36:12 +bmispelon | vlt: as a matter of fact, I can │
12:40:47 +bmispelon | vlt: something weird is definitely │
| going on... First I thought it might │
| be because your app is called "name" │
| but I changed that and I still see │
| the same behavior │
12:47:50 +bmispelon | vlt: I don't understand what's going │
| on here, sorry :( │
12:48:16 +bmispelon | I'll see if I can narrow down the │
| reproduction steps later today │
14:18:02 vlt | Hello again. I created a minimal │
| working example for the weird │
| migrations thing: │
| https://github.com/vlt/migrations If │
| you run makemigrations it will create │
| the very same one over and over │
| again. │
14:18:47 +apollo13 | lets see │
14:19:27 +apollo13 | vlt: indeed │
14:28:00 +apollo13 | vlt: oh │
14:29:57 +apollo13 | vlt: seems like a bug, it compares │
| app1.Model1 to app1.model1 -- please │
| open a ticket with that information │
14:30:18 +apollo13 | somehwere a .lower() is missing │
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/27297>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Sep 29, 2016, 4:18:02 PM9/29/16
to django-...@googlegroups.com
#27297: makemigrations creates the same migration again and again (because it fails
to compare uppercase to lowercase model names)
--------------------------------+--------------------------------------

Reporter: Daniel Musketa | Owner: nobody
Type: Bug | Status: new
Component: Migrations | Version: 1.10
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
--------------------------------+--------------------------------------
Changes (by Daniel Musketa):

* cc: daniel.musketa@… (added)
* needs_better_patch: => 0
* needs_tests: => 0
* needs_docs: => 0


Old description:

New description:

Tested and affected Django versions:

- 1.7
- 1.8
- 1.9
- 1.9.6
- 1.10.1

The new file {{{0003_auto_20160929_1358.py}}}:


class Migration(migrations.Migration):

--

Comment:

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
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/27297#comment:1>

Django

unread,
Sep 29, 2016, 9:08:58 PM9/29/16
to django-...@googlegroups.com
#27297: Non-deterministic infinite AlterField migrations created for foreign key
--------------------------------+------------------------------------

Reporter: Daniel Musketa | Owner: nobody
Type: Bug | Status: new
Component: Migrations | Version: 1.10
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted

Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
--------------------------------+------------------------------------
Changes (by Tim Graham):

* stage: Unreviewed => Accepted


Comment:

I'm not sure about the cause, but the root issue is that
[https://github.com/django/django/blob/bceade84a7337b1f27c3bf7ec158051128f3324b/django/db/migrations/autodetector.py#L909-L911
deconstruction] is returning non-deterministic results. Sometimes the
fields appear equal and sometimes the case differs in the `to` field, as
you said.

--
Ticket URL: <https://code.djangoproject.com/ticket/27297#comment:2>

Django

unread,
Sep 30, 2016, 9:14:06 AM9/30/16
to django-...@googlegroups.com
#27297: Non-deterministic infinite AlterField migrations created for foreign key
--------------------------------+------------------------------------
Reporter: Daniel Musketa | Owner: nobody
Type: Bug | Status: new
Component: Migrations | Version: 1.10
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
--------------------------------+------------------------------------

Comment (by Baptiste Mispelon):

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?

--
Ticket URL: <https://code.djangoproject.com/ticket/27297#comment:3>

Django

unread,
Sep 30, 2016, 11:42:34 AM9/30/16
to django-...@googlegroups.com
#27297: Non-deterministic infinite AlterField migrations created for foreign key
--------------------------------+------------------------------------
Reporter: Daniel Musketa | Owner: nobody
Type: Bug | Status: new
Component: Migrations | Version: 1.10
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
--------------------------------+------------------------------------

Comment (by Daniel Musketa):

Replying to [comment:3 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?

--
Ticket URL: <https://code.djangoproject.com/ticket/27297#comment:4>

Django

unread,
Oct 1, 2016, 5:46:13 PM10/1/16
to django-...@googlegroups.com
#27297: infinite AlterField migrations created for foreign key after case-only
model name change
--------------------------------+------------------------------------

Reporter: Daniel Musketa | Owner: nobody
Type: Bug | Status: new
Component: Migrations | Version: 1.10
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
--------------------------------+------------------------------------

Old description:

> Tested and affected Django versions:

> - 1.7
> - 1.8
> - 1.9

New description:

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.

--

Comment (by Daniel Musketa):

I narrowed down the cause, created a new example and changed the ticket
description accordingly.

--
Ticket URL: <https://code.djangoproject.com/ticket/27297#comment:5>

Django

unread,
Oct 1, 2016, 5:47:05 PM10/1/16
to django-...@googlegroups.com
#27297: infinite AlterField migrations created for foreign key after case-only
model name change
--------------------------------+------------------------------------
Reporter: Daniel Musketa | Owner: nobody
Type: Bug | Status: new
Component: Migrations | Version: 1.10
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
--------------------------------+------------------------------------
Description changed by Daniel Musketa:

Old description:

> 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.

New description:

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.

--

--
Ticket URL: <https://code.djangoproject.com/ticket/27297#comment:6>

Django

unread,
Nov 4, 2016, 2:34:30 PM11/4/16
to django-...@googlegroups.com
#27297: infinite AlterField migrations created for foreign key after case-only
model name change
--------------------------------+------------------------------------
Reporter: Daniel Musketa | Owner: nobody
Type: Bug | Status: new
Component: Migrations | Version: master

Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
--------------------------------+------------------------------------
Changes (by Anton Samarchyan):

* cc: desecho@… (added)
* has_patch: 0 => 1
* version: 1.10 => master


Comment:

Added [https://github.com/django/django/pull/7469 PR 7469] - Ignore case-
only model name changes in migration autodetector

--
Ticket URL: <https://code.djangoproject.com/ticket/27297#comment:7>

Django

unread,
Nov 4, 2016, 8:29:09 PM11/4/16
to django-...@googlegroups.com
#27297: infinite AlterField migrations created for foreign key after case-only
model name change
--------------------------------+------------------------------------
Reporter: Daniel Musketa | Owner: nobody
Type: Bug | Status: new
Component: Migrations | Version: master
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1

Easy pickings: 0 | UI/UX: 0
--------------------------------+------------------------------------
Changes (by Simon Charette):

* needs_better_patch: 0 => 1


Comment:

Left some comments on the PR.

--
Ticket URL: <https://code.djangoproject.com/ticket/27297#comment:8>

Django

unread,
Nov 30, 2016, 3:29:36 PM11/30/16
to django-...@googlegroups.com
#27297: infinite AlterField migrations created for foreign key after case-only
model name change
--------------------------------+------------------------------------
Reporter: Daniel Musketa | Owner: nobody
Type: Bug | Status: new
Component: Migrations | Version: master
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
--------------------------------+------------------------------------
Changes (by Anton Samarchyan):

* needs_better_patch: 1 => 0
* has_patch: 1 => 0


Comment:

My patch used an incorrect approach. Need a new patch.

--
Ticket URL: <https://code.djangoproject.com/ticket/27297#comment:9>

Django

unread,
Jan 17, 2017, 4:22:40 PM1/17/17
to django-...@googlegroups.com
#27297: infinite AlterField migrations created for foreign key after case-only
model name change
--------------------------------+-------------------------------------

Reporter: Daniel Musketa | Owner: nobody
Type: Bug | Status: closed
Component: Migrations | Version: master
Severity: Normal | Resolution: duplicate

Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
--------------------------------+-------------------------------------
Changes (by Simon Charette):

* status: new => closed
* resolution: => duplicate


Comment:

Duplicate of #23916.

--
Ticket URL: <https://code.djangoproject.com/ticket/27297#comment:10>

Reply all
Reply to author
Forward
0 new messages