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

Reply via email to