[Django] #25551: makemigrations when adding a ForeignKey to a newly created model along with a unique_together constraint must create fields before the unique_together constraint

10 views
Skip to first unread message

Django

unread,
Oct 13, 2015, 10:05:25 AM10/13/15
to django-...@googlegroups.com
#25551: makemigrations when adding a ForeignKey to a newly created model along with
a unique_together constraint must create fields before the unique_together
constraint
----------------------------+--------------------
Reporter: mssnlayam | Owner: nobody
Type: Bug | Status: new
Component: Migrations | Version: 1.8
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Easy pickings: 0 | UI/UX: 0
----------------------------+--------------------
When adding a new model and a `ForeignKey` to it as well a
`unique_together` constraint for the `ForeignKey` field, Django migrations
should create the field before applying the `unique_together` constraint.

In the example below, I am adding a new `Author` model, a field to this
model and a `unique_together` constraint for this field.

{{{#!diff
from django.db import models

+class Author(models.Model):
+ name = models.CharField(max_length=255)
+
class Book(models.Model):
name = models.CharField(max_length=255)
+ author = models.ForeignKey(Author, null=True)
+ class Meta:
+ unique_together = (
+ ('name', 'author'),
+ )
}}}

Django's migrations framework produces the following summary output:

{{{
Migrations for 'testapp':
0002_auto_20151013_1354.py:
- Create model Author
- Alter unique_together for book (1 constraint(s))
- Add field author to book
}}}

Here's the relevant portion of the migrations file:

{{{#!python
operations = [
migrations.CreateModel(
name='Author',
fields=[
('id', models.AutoField(verbose_name='ID',
serialize=False, auto_created=True, primary_key=True)),
('name', models.CharField(max_length=255)),
],
),
migrations.AlterUniqueTogether(
name='book',
unique_together=set([('name', 'author')]),
),
migrations.AddField(
model_name='book',
name='author',
field=models.ForeignKey(to='testapp.Author', null=True),
),
]
}}}

This migration fails with the following stacktrace:
{{{
Operations to perform:
Apply all migrations: testapp
Running migrations:
Rendering model states... DONE
Applying testapp.0002_auto_20151013_1354...Traceback (most recent call
last):
File "./manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/home/vagrant/testunique-env/local/lib/python2.7/site-
packages/django/core/management/__init__.py", line 351, in
execute_from_command_line
utility.execute()
File "/home/vagrant/testunique-env/local/lib/python2.7/site-
packages/django/core/management/__init__.py", line 343, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/vagrant/testunique-env/local/lib/python2.7/site-
packages/django/core/management/base.py", line 394, in run_from_argv
self.execute(*args, **cmd_options)
File "/home/vagrant/testunique-env/local/lib/python2.7/site-
packages/django/core/management/base.py", line 445, in execute
output = self.handle(*args, **options)
File "/home/vagrant/testunique-env/local/lib/python2.7/site-
packages/django/core/management/commands/migrate.py", line 222, in handle
executor.migrate(targets, plan, fake=fake, fake_initial=fake_initial)
File "/home/vagrant/testunique-env/local/lib/python2.7/site-
packages/django/db/migrations/executor.py", line 110, in migrate
self.apply_migration(states[migration], migration, fake=fake,
fake_initial=fake_initial)
File "/home/vagrant/testunique-env/local/lib/python2.7/site-
packages/django/db/migrations/executor.py", line 148, in apply_migration
state = migration.apply(state, schema_editor)
File "/home/vagrant/testunique-env/local/lib/python2.7/site-
packages/django/db/migrations/migration.py", line 115, in apply
operation.database_forwards(self.app_label, schema_editor, old_state,
project_state)
File "/home/vagrant/testunique-env/local/lib/python2.7/site-
packages/django/db/migrations/operations/models.py", line 359, in
database_forwards
getattr(new_model._meta, self.option_name, set()),
File "/home/vagrant/testunique-env/local/lib/python2.7/site-
packages/django/db/backends/sqlite3/schema.py", line 219, in
alter_unique_together
self._remake_table(model, override_uniques=new_unique_together)
File "/home/vagrant/testunique-env/local/lib/python2.7/site-
packages/django/db/backends/sqlite3/schema.py", line 140, in _remake_table
self.create_model(temp_model)
File "/home/vagrant/testunique-env/local/lib/python2.7/site-
packages/django/db/backends/base/schema.py", line 272, in create_model
columns = [model._meta.get_field(field).column for field in fields]
File "/home/vagrant/testunique-env/local/lib/python2.7/site-
packages/django/db/models/options.py", line 554, in get_field
raise FieldDoesNotExist('%s has no field named %r' %
(self.object_name, field_name))
django.core.exceptions.FieldDoesNotExist: Book has no field named
u'author'
}}}

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

Django

unread,
Oct 13, 2015, 10:46:26 AM10/13/15
to django-...@googlegroups.com
#25551: makemigrations when adding a ForeignKey to a newly created model along with
a unique_together constraint must create fields before the unique_together
constraint
----------------------------+------------------------------------

Reporter: mssnlayam | Owner: nobody
Type: Bug | Status: new
Component: Migrations | Version: 1.8
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 timgraham):

* needs_better_patch: => 0
* needs_docs: => 0
* needs_tests: => 0
* stage: Unreviewed => Accepted


Comment:

Seems similar to #22035 but I can reproduce the issue on master.

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

Django

unread,
Nov 5, 2015, 4:09:11 PM11/5/15
to django-...@googlegroups.com
#25551: makemigrations when adding a ForeignKey to a newly created model along with
a unique_together constraint must create fields before the unique_together
constraint
----------------------------+---------------------------------------
Reporter: mssnlayam | Owner: avojnovicDk
Type: Bug | Status: assigned
Component: Migrations | Version: 1.8

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 avojnovicDk):

* status: new => assigned
* owner: nobody => avojnovicDk


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

Django

unread,
Nov 7, 2015, 9:53:34 AM11/7/15
to django-...@googlegroups.com
#25551: makemigrations when adding a ForeignKey to a newly created model along with
a unique_together constraint must create fields before the unique_together
constraint
----------------------------+---------------------------------------
Reporter: mssnlayam | Owner: avojnovicDk
Type: Bug | Status: assigned
Component: Migrations | Version: 1.8

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 avojnovicDk):

* has_patch: 0 => 1


Comment:

This happens for the very specific edge case: If you create a model, make
migrations for that model, and then add a foreign key to another model
that didn't exist previously with unique together, the order of the action
in the new migration will not be correct: it will try to alter unique
together and then add the field used in unique together.
I made PR with fix for this.

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

Django

unread,
Nov 18, 2015, 6:27:01 PM11/18/15
to django-...@googlegroups.com
#25551: makemigrations when adding a ForeignKey to a newly created model along with
a unique_together constraint must create fields before the unique_together
constraint
----------------------------+---------------------------------------
Reporter: mssnlayam | Owner: avojnovicDk
Type: Bug | Status: assigned
Component: Migrations | Version: 1.8

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 timgraham):

* needs_better_patch: 0 => 1


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

Django

unread,
Nov 19, 2015, 7:40:23 PM11/19/15
to django-...@googlegroups.com
#25551: makemigrations when adding a ForeignKey to a newly created model along with
a unique_together constraint must create fields before the unique_together
constraint
----------------------------+---------------------------------------
Reporter: mssnlayam | Owner: avojnovicDk
Type: Bug | Status: assigned
Component: Migrations | Version: 1.8

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 avojnovicDk):

* needs_better_patch: 1 => 0


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

Django

unread,
Nov 20, 2015, 12:21:41 PM11/20/15
to django-...@googlegroups.com
#25551: makemigrations when adding a ForeignKey to a newly created model along with
a unique_together constraint must create fields before the unique_together
constraint
----------------------------+---------------------------------------
Reporter: mssnlayam | Owner: avojnovicDk
Type: Bug | Status: closed
Component: Migrations | Version: 1.8
Severity: Normal | Resolution: fixed

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 Tim Graham <timograham@…>):

* status: assigned => closed
* resolution: => fixed


Comment:

In [changeset:"73a6ab6382809d5452907dcff5767403d8d66985" 73a6ab63]:
{{{
#!CommitTicketReference repository=""
revision="73a6ab6382809d5452907dcff5767403d8d66985"
Fixed #25551 -- Fixed migration operations ordering when adding fields and
a unique_together constraint.
}}}

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

Reply all
Reply to author
Forward
0 new messages