[Django] #25648: Unable to modify or delete unique_together Model constraint (PostgreSQL)

8 views
Skip to first unread message

Django

unread,
Oct 30, 2015, 9:37:35 PM10/30/15
to django-...@googlegroups.com
#25648: Unable to modify or delete unique_together Model constraint (PostgreSQL)
-------------------------------+--------------------
Reporter: MasterKale | Owner: nobody
Type: Uncategorized | Status: new
Component: Uncategorized | Version: 1.8
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------
I'm having the worst luck making any changes to a '''unique_together'''
constraint on one of my Models. I want to preface this with the fact that
this seems very similar to ticket #23614.

Here's how my model started out:

{{{
class Skill(models.Model):
company = models.IntegerField(default=1)
title = models.CharField(max_length=50)

class Meta:
unique_together = ['company', 'title']
}}}

I added a '''location''' ForeignKey field to the model, with ''null=True''
set so that I could create a custom migration afterwards to populate the
new field. After creating the custom migration, I then ran
''makemigration'' after 1) removing the ''null=True'' constraint on the
'''location''' field, 2) altering '''unique_together''' to swap out
'''location''' for '''company''', and 3) deleting the '''company''' field.

This is what I ended up with (and remains the ideal state of this Model):

{{{
class Skill(models.Model):
location = models.ForeignKey(Location, related_name="skills")
title = models.CharField(max_length=50)

class Meta:
unique_together = ['location', 'title']
}}}

And this is the migration that Django generated after I made all three
changes to Skill:

{{{
operations = [
migrations.AlterField(
model_name='skill',
name='location',
field=models.ForeignKey(related_name='skills',
to='serverapp.Location'),
),
migrations.AlterUniqueTogether(
name='skill',
unique_together=set([('location', 'title')]),
),
migrations.RemoveField(
model_name='skill',
name='company',
),
]
}}}

This migration continually error'd out until I removed the
AlterUniqueTogether migration, at which point it ran fine.

Unfortunately, this left me in a bad spot as I could no longer make any
changes to '''unique_together''' because (paraphrasing a bit) "the
'''company''' field no longer existed".

In an effort to rollback things somewhat, I added a '''company''' field
back into the Skill Model as a simple IntegerField with ''default=1''. I
hoped that I could trick the migration system into a state in which it
could modify '''unique_together''' to the desired relationship. This
migration processed successfully, so now I had the following Model:

{{{
class Skill(models.Model):
company = models.IntegerField(default=1)
location = models.ForeignKey(Location, related_name="skills")
title = models.CharField(max_length=50)

class Meta:
unique_together = ['location', 'title']
}}}

Since modifying the constraint kept failing to go through, I then decided
to do away with the constraint altogether:

{{{
class Skill(models.Model):
company = models.IntegerField(default=1)
location = models.ForeignKey(Location, related_name="skills")
title = models.CharField(max_length=50)

class Meta:
# unique_together = ['location', 'title']
}}}

This generated the following expected migration file:

{{{
operations = [
migrations.AlterUniqueTogether(
name='skill',
unique_together=set([]),
),
]
}}}

This is where I'm currently stuck. Attemping to migrate this change
generates the following error:

{{{
Operations to perform:
Synchronize unmigrated apps: rest_framework_swagger, rest_framework,
corsheaders, messages, staticfiles
Apply all migrations: authtoken, sessions, contenttypes, reversion,
serverapp, auth, admin
Synchronizing apps without migrations:
Creating tables...
Running deferred SQL...
Installing custom SQL...
Running migrations:
Rendering model states... DONE
Applying serverapp.0059_auto_20151030_1823...Traceback (most recent call
last):
File "shiftserver\manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "C:\Python34\lib\site-packages\django\core\management\__init__.py",
line 338, in execute_from_command_line
utility.execute()
File "C:\Python34\lib\site-packages\django\core\management\__init__.py",
line 330, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "C:\Python34\lib\site-packages\django\core\management\base.py",
line 390, in run_from_argv
self.execute(*args, **cmd_options)
File "C:\Python34\lib\site-packages\django\core\management\base.py",
line 441, in execute
output = self.handle(*args, **options)
File "C:\Python34\lib\site-
packages\django\core\management\commands\migrate.py", line 221, in handle
executor.migrate(targets, plan, fake=fake, fake_initial=fake_initial)
File "C:\Python34\lib\site-packages\django\db\migrations\executor.py",
line 110, in migrate
self.apply_migration(states[migration], migration, fake=fake,
fake_initial=fake_initial)
File "C:\Python34\lib\site-packages\django\db\migrations\executor.py",
line 147, in apply_migration
state = migration.apply(state, schema_editor)
File "C:\Python34\lib\site-packages\django\db\migrations\migration.py",
line 115, in apply
operation.database_forwards(self.app_label, schema_editor, old_state,
project_state)
File "C:\Python34\lib\site-
packages\django\db\migrations\operations\models.py", line 355, in
database_forwards
getattr(new_model._meta, self.option_name, set()),
File "C:\Python34\lib\site-packages\django\db\backends\base\schema.py",
line 322, in alter_unique_together
", ".join(columns),
ValueError: Found wrong number (0) of constraints for
serverapp_skill(company, title)
}}}

I peeked at schema.py:322 and while it looks as though
'''alter_unique_together()''' isn't designed to handle being passed in 0
parameters for unique_together, I'm not confident enough in my reading of
'''self._constraint_names()''' to say that the issue exists somewhere in
there.

Any ideas what might be going on? I googled the hell out of this issue but
couldn't find anything beyond the ticket I mentioned above, and even
that's specific to MySQL so it didn't seem to be of much help.

I've lost a couple of hours to this problem. I really hope it's not
something stupid I'm trying to do...

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

Django

unread,
Oct 31, 2015, 12:55:19 PM10/31/15
to django-...@googlegroups.com
#25648: Unable to modify or delete unique_together Model constraint (PostgreSQL)
-------------------------------+--------------------------------------

Reporter: MasterKale | Owner: nobody
Type: Uncategorized | Status: new
Component: Uncategorized | Version: 1.8
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 shaib):

* needs_better_patch: => 0
* needs_tests: => 0
* needs_docs: => 0


Comment:

Hello,

You seem to have left out one of the most important pieces of the puzzle
-- the exact error you encountered at first when trying to change the
unique-together.

I'm referring to the line that says:

> This migration continually error'd out until I removed the
AlterUniqueTogether migration, at which point it ran fine.

What was the error?

All in all, you appear to have found a true problem in Django with respect
to removal of all unique_together constraints, but other than that, the
report is a little unclear.

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

Django

unread,
Oct 31, 2015, 2:22:15 PM10/31/15
to django-...@googlegroups.com
#25648: Unable to modify or delete unique_together Model constraint (PostgreSQL)
-------------------------------+--------------------------------------

Reporter: MasterKale | Owner: nobody
Type: Uncategorized | Status: new
Component: Uncategorized | Version: 1.8
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
-------------------------------+--------------------------------------

Comment (by MasterKale):

I was afraid you were going to ask for that. Unfortunately by the time I'd
started writing this ticket I'd cleared my console and could no longer see
the entire error message.

Fortunately Google knows everything about me and my past internet
searches, so I was able to recover the following from one of my earlier
searches when I started troubleshooting things:

"Found wrong number of constraints (2) for"

I believe the entire message read something like this:

Found wrong number of constraints (2) for serverapp_skill(company_id,
title)

'''But before I go any further...'''

Just now, in an effort to recreate the above error message so I could get
a verbatim quote, the migration actually worked. I restored the database
from an earlier backup I'd taken last month, migrated up until I started
experiencing issues, then made a migration that removed the '''company'''
field, removed the '''null=True''' constraint, and updated
'''unique_together''' to replace ''company'' with ''location''.

The generated migration file looked exactly the same as I posted
yesterday:

{{{
operations = [
migrations.AlterField(
model_name='skill',
name='location',
field=models.ForeignKey(related_name='skills',
to='serverapp.Location'),
),
migrations.AlterUniqueTogether(
name='skill',
unique_together=set([('location', 'title')]),
),
migrations.RemoveField(
model_name='skill',
name='company',
),
]
}}}

The only difference is that, when I went to migrate just now it went
through without issue. The tables updated constraints and removed columns
just fine. I even checked the '''unique_together''' constraint manually
via pgAdmin III and verified that it updated to reference '''location'''
instead of '''company'''.

I have no idea why it went through this time. I literally did the exact
same thing this morning that I first attempted yesterday, and for some
reason the migration just decided to work.

Now I'm worried about migrating my production server...

In any case, would it be useful to talk more about the original error
message? Is there anything in there that might shed light on this mystery?
I'm glad the migration went through this second time but I'm also scared
that I have nothing to look out for in case this issue rears its ugly head
again.

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

Django

unread,
Oct 31, 2015, 6:10:58 PM10/31/15
to django-...@googlegroups.com
#25648: Unable to modify or delete unique_together Model constraint (PostgreSQL)
-------------------------------+--------------------------------------

Reporter: MasterKale | Owner: nobody
Type: Uncategorized | Status: new
Component: Uncategorized | Version: 1.8
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
-------------------------------+--------------------------------------

Comment (by timgraham):

I'm afraid that unless you can provide steps to reproduce a problem, we
won't be able to provide much help. It seems that somehow your database
might have been missing constraints or something.

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

Django

unread,
Nov 2, 2015, 1:03:31 PM11/2/15
to django-...@googlegroups.com
#25648: Unable to modify or delete unique_together Model constraint (PostgreSQL)
-------------------------------+--------------------------------------
Reporter: MasterKale | Owner: nobody
Type: Uncategorized | Status: closed
Component: Uncategorized | Version: 1.8
Severity: Normal | Resolution: invalid
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 MasterKale):

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


Comment:

I'm going to go ahead and close this ticket. I ended up cloning my
production server and successfully ran it through all of the migrations,
so it seems that something was hosed within the old dev database itself.

Thanks for your time.

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

Reply all
Reply to author
Forward
0 new messages