#29123: Generated migration orders Add/Remove Field incorrectly, causing
OperationalError
----------------------------+--------------------------------------
Reporter: Ed Morley | Owner: nobody
Type: Bug | Status: new
Component: Migrations | Version: master
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
----------------------------+--------------------------------------
Description changed by Ed Morley:
Old description:
> Replacing an integer field with a foreign key of the same name, results
> in an `OperationalError` when creating/applying the migration.
>
> This affects Django master + v1.11.10, and both the SQLite and MySQL
> backends (others not tested).
>
> == STR:
> 1. Git clone `https://github.com/edmorley/django-migration-int-to-fk-
> testcase`
> 2. `pip install https://github.com/django/django/archive/master.zip`
> 3. `./manage.py migrate`
> 4. `cp testapp/models_new.py testapp/models.py`
> 5. `./manage.py makemigrations --name broken_migration`
> 6. `./manage.py migrate`
>
> == Expected:
>
> New migration is created/applied successfully, which converts from the
> [https://github.com/edmorley/django-migration-int-to-fk-
> testcase/blob/master/testapp/models.py original model] to the
> [https://github.com/edmorley/django-migration-int-to-fk-
> testcase/blob/master/testapp/models_new.py new model].
>
> == Actual:
>
> The new `0002_broken_migration.py` migration incorrectly lists the
> `AddField`
> operation before the `RemoveField` operation...
>
> {{{#!python
> operations = [
> migrations.AddField(
> model_name='bar',
> name='foo',
> field=models.ForeignKey(null=True,
> on_delete=django.db.models.deletion.CASCADE, to='testapp.Foo'),
> ),
> migrations.RemoveField(
> model_name='bar',
> name='foo_id',
> ),
> migrations.AlterUniqueTogether(
> name='bar',
> unique_together={('name', 'foo')},
> ),
> ]
> }}}
>
> Which results in an exception at step 6...
>
> {{{#!bash
> $ ./manage.py migrate
> Operations to perform:
> Apply all migrations: admin, auth, contenttypes, sessions, testapp
> Running migrations:
> Applying testapp.0002_broken_migration...Traceback (most recent call
> last):
> File "/c/Users/Ed/.virtualenvs/django-master/lib/python3.6/site-
> packages/django/db/backends/utils.py", line 83, in _execute
> return self.cursor.execute(sql)
> File "/c/Users/Ed/.virtualenvs/django-master/lib/python3.6/site-
> packages/django/db/backends/sqlite3/base.py", line 290, in execute
> return Database.Cursor.execute(self, query)
> sqlite3.OperationalError: duplicate column name: foo_id
> }}}
>
> == Additional notes:
> * Without the `unique_together` on model `Bar`, the bug does not occur.
> * This affects both the SQLite backend and the MySQL backend (others not
> tested).
> * At time of testing, django master was at revision
> `6d794fb76212bb8a62fe2cd97cff173054e1c626`.
New description:
Replacing an integer field with a foreign key of the same name, results in
an `OperationalError` when creating/applying the migration.
This affects Django master + v1.11.10, and both the SQLite and MySQL
backends (others not tested).
== STR:
1. Git clone [https://github.com/edmorley/django-migration-int-to-fk-
testcase https://github.com/edmorley/django-migration-int-to-fk-testcase]
2. `pip install https://github.com/django/django/archive/master.zip`
3. `./manage.py migrate`
4. `cp testapp/models_new.py testapp/models.py`
5. `./manage.py makemigrations --name broken_migration`
6. `./manage.py migrate`
== Expected:
New migration is created/applied successfully, which converts from the
[https://github.com/edmorley/django-migration-int-to-fk-
testcase/blob/master/testapp/models.py original model] to the
[https://github.com/edmorley/django-migration-int-to-fk-
testcase/blob/master/testapp/models_new.py new model].
== Actual:
The new `0002_broken_migration.py` migration incorrectly lists the
`AddField` operation before the `RemoveField` operation...
{{{#!python
operations = [
migrations.AddField(
model_name='bar',
name='foo',
field=models.ForeignKey(null=True,
on_delete=django.db.models.deletion.CASCADE, to='testapp.Foo'),
),
migrations.RemoveField(
model_name='bar',
name='foo_id',
),
migrations.AlterUniqueTogether(
name='bar',
unique_together={('name', 'foo')},
),
]
}}}
Which results in an exception at step 6...
{{{#!bash
$ ./manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions, testapp
Running migrations:
Applying testapp.0002_broken_migration...Traceback (most recent call
last):
File ".../site-packages/django/db/backends/utils.py", line 83, in
_execute
return self.cursor.execute(sql)
File ".../site-packages/django/db/backends/sqlite3/base.py", line 290,
in execute
return Database.Cursor.execute(self, query)
sqlite3.OperationalError: duplicate column name: foo_id
}}}
== Additional notes:
* Without the `unique_together` on model `Bar`, the bug does not occur.
* This affects both the SQLite backend and the MySQL backend (others not
tested).
* At time of testing, django master was at revision
`6d794fb76212bb8a62fe2cd97cff173054e1c626`.
* The above was using Python 3.6.2.
--
--
Ticket URL: <https://code.djangoproject.com/ticket/29123#comment:1>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/066.f25229a804921bf422931b6b2b09b089%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.