Arpit
Arpit

Reputation: 476

Problem with Updating unique together constraint Django

Tried to updating unqiue_together constraint using Django-ORM

While Migrating getting following error :

File "/Applications/PyCharm CE.app/Contents/helpers/pydev/pydevd.py", line 1664, in <module>
main()
File "/Applications/PyCharm CE.app/Contents/helpers/pydev/pydevd.py", line 1658, in main
globals = debugger.run(setup['file'], None, None, is_module)
File "/Applications/PyCharm CE.app/Contents/helpers/pydev/pydevd.py", line 1068, in run
pydev_imports.execfile(file, globals, locals)  # execute the script
File "/Applications/PyCharm CE.app/Contents/helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile
exec(compile(contents+"\n", file, 'exec'), glob, loc)
File "/Users/arpitkoolwal/DEV/Gateway-26Oct/gateway/gateway/manage.py", line 24, in <module>
execute_from_command_line(sys.argv)
File "/Users/arpitkoolwal/DEV/cld/pyenv3/lib/python3.6/site-packages/django/core/management/__init__.py", line 364, in execute_from_command_line
utility.execute()
File "/Users/arpitkoolwal/DEV/cld/pyenv3/lib/python3.6/site-packages/django/core/management/__init__.py", line 356, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/Users/arpitkoolwal/DEV/cld/pyenv3/lib/python3.6/site-packages/django/core/management/base.py", line 283, in run_from_argv
self.execute(*args, **cmd_options)
File "/Users/arpitkoolwal/DEV/cld/pyenv3/lib/python3.6/site-packages/django/core/management/base.py", line 330, in execute
output = self.handle(*args, **options)
File "/Users/arpitkoolwal/DEV/cld/pyenv3/lib/python3.6/site-packages/django/core/management/commands/migrate.py", line 204, in handle
fake_initial=fake_initial,
File "/Users/arpitkoolwal/DEV/cld/pyenv3/lib/python3.6/site-packages/django/db/migrations/executor.py", line 115, in migrate
state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)
File "/Users/arpitkoolwal/DEV/cld/pyenv3/lib/python3.6/site-packages/django/db/migrations/executor.py", line 145, in _migrate_all_forwards
state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
File "/Users/arpitkoolwal/DEV/cld/pyenv3/lib/python3.6/site-packages/django/db/migrations/executor.py", line 244, in apply_migration
state = migration.apply(state, schema_editor)
File "/Users/arpitkoolwal/DEV/cld/pyenv3/lib/python3.6/site-packages/django/db/migrations/migration.py", line 129, in apply
operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
File "/Users/arpitkoolwal/DEV/cld/pyenv3/lib/python3.6/site-packages/django/db/migrations/operations/models.py", line 536, in database_forwards
getattr(new_model._meta, self.option_name, set()),
File "/Users/arpitkoolwal/DEV/cld/pyenv3/lib/python3.6/site-packages/django/db/backends/base/schema.py", line 365, in alter_unique_together
self._delete_composed_index(model, fields, {'unique': True}, self.sql_delete_unique)
File "/Users/arpitkoolwal/DEV/cld/pyenv3/lib/python3.6/site-packages/django/db/backends/mysql/schema.py", line 88, in _delete_composed_index
return super(DatabaseSchemaEditor, self)._delete_composed_index(model, fields, *args)
File "/Users/arpitkoolwal/DEV/cld/pyenv3/lib/python3.6/site-packages/django/db/backends/base/schema.py", line 394, in _delete_composed_index
", ".join(columns), ValueError: Found wrong number (0) of constraints for test(a, b)

Django : 1.11.15

Error Ticket : Django-Offical

Can anyone tell me, How can we modify existing unique constraint using Django-ORM ?

EDIT :

Model -

class test(models.Model):
    a = models.CharField(max_length=500, blank=True, null=True)
    b = models.CharField(max_length=500, blank=True, null=True)
    c = models.CharField(max_length=500, blank=True, null=True)
    d = models.CharField(max_length=500, blank=True, null=True)
    class Meta:
     unique_together = ('a', 'b')

Migration Code :

class Migration(migrations.Migration):

dependencies = [
    ('demo', '0230_auto_20181106_1243'),
]

operations = [
    migrations.AlterUniqueTogether(
        name='test',
        unique_together=set([a,b]),
    ),
]

Upvotes: 0

Views: 3527

Answers (3)

tonthon
tonthon

Reputation: 41

One situation I know where that problem occurs is when you upgraded an existing Django application and you started the migration history from scratch. The initial migration script may initialize the constraint in an order different from the one in the database. So when you remove (or modify) the unique_together constraint it doesn't match.

The model used to be

class MyModel(models.Model):
    class Meta:
        verbose_name = "My Model"
        unique_together = (('name', 'label'),)
    name = models.CharField(max_length=50)
    label = models.CharField(max_length=100)

It has been changed to

class MyModel(models.Model):
    class Meta:
        verbose_name = "My Model"
    name = models.CharField(max_length=50)

The database shows :

UNIQUE KEY `app_mymodel_name_77dd4fb8f340a397_uniq`       (`label`, `name`)

In the initial migration script 0001_initial.py

migrations.AlterUniqueTogether(                                         
    name='mymodel',                                                   
    unique_together=set([('name', 'label', )]),               
),   

In the new migration script 0007_auto_20220916_1454.py

migrations.AlterUniqueTogether(                                         
    name='mymodel',                                                   
    unique_together=set([]),               
), 

Solution : Change the order of the arguments of the migrations.AlterUniqueTogether call in the initialization migration script (0001_initial.py)

migrations.AlterUniqueTogether(                                         
    name='mymodel',                                                   
    unique_together=set([('label', 'name', )]),               
),   

And launch the migration again.

Upvotes: 0

jdlm
jdlm

Reputation: 13

I just ran into this error, took quite sometime to figure out. I borrowed from the accepted answer and commented out the most recent AlterUniqueTogether in the relevant migration file. Unsure if this will cause long term instability, but it allowed the migration to work.

Upvotes: 0

est
est

Reputation: 11885

How I solved the problem:

  1. python -m pdb manage.py migrate
  2. type up to go upper frame. It will go to

    ./python3.6/site-packages/django/db/backends/base/schema.py(363)alter_unique_together() -> self._delete_composed_index(model, fields, {'unique': True}, self.sql_delete_unique)

  3. type a to show variables

Notice

old_unique_together = {('a', 'b')}
new_unique_together = {('a', 'b', 'c')}

that the old_unique_together does not exist, according to pg \d tablename

  1. Go to old migration files and find old migrations.AlterUniqueTogether, comment them, then run the migration again.
  2. ???
  3. profit.

Upvotes: 1

Related Questions