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

-- 
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 django-updates+unsubscr...@googlegroups.com.
To post to this group, send email to django-updates@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/053.acfbc4be0537ac1c5347c908e7b24068%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to