Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django 1.9 can't modify unique_together (ValueError) wrong number of constrains

I created my models using inspectdb, it struck me odd at the time that django generated the following since there is just one such index, but i let it be

unique_together = (('p_id', 'v_id', 'sku',), ('p_id', 'v_id', 'sku',))

now i'm trying to add 'sku2' to this index and 'migrate' is failing with the following:

 File "/home/user/.pyenv/versions/2.7.11/envs/master2/lib/python2.7/site-packages/django/db/backends/base/schema.py", line 347, in _delete_composed_index
    ", ".join(columns),
ValueError: Found wrong number (2) of constraints for vendor_products(p_id, v_id, sku)

this is my model:

class Products(models.Model):
    p_id = models.OneToOneField(MasterProducts, models.DO_NOTHING, db_column='p_id', primary_key=True)
    v_id = models.ForeignKey('Sellers', models.DO_NOTHING, db_column='v_id')
    sku = models.TextField()
    sku2 = models.TextField(blank=True, null=True)

    class Meta:
        managed = True
        db_table = 'products'
        unique_together = (('p_id', 'v_id', 'sku',), ('p_id', 'v_id', 'sku',))

i tried changing unique_together to (('p_id', 'v_id', 'sku',),) and ('p_id', 'v_id', 'sku',) with the same result.

also i tried manually deleting the unique index using the db and recreating it using django and it still won't let me add sku2.

Why is this happening, how do i fix it?

like image 372
jayshilling Avatar asked Dec 21 '15 16:12

jayshilling


1 Answers

I did not dig it deeper, but examined sources a bit of my Django 1.8. I think this code part would be the same.

My guess is that you have created wrong constraints with this statement:

unique_together = (('p_id', 'v_id', 'sku',), ('p_id', 'v_id', 'sku',))

You have created migration and applied it. It created two same constraints in the database. Technically it is allowed, but has no sense.

After that you tried to change it and here you got the error due to Django's validation in django.db.backends.base.schema._delete_composed_index() - it collects all constraints from the database and verifies that there is only one:

def _delete_composed_index(self, model, fields, constraint_kwargs, sql):
    columns = [model._meta.get_field(field).column for field in fields]
    constraint_names = self._constraint_names(model, columns, **constraint_kwargs)
    if len(constraint_names) != 1:
        raise ValueError("Found wrong number (%s) of constraints for %s(%s)" % (
            len(constraint_names),
            model._meta.db_table,
            ", ".join(columns),
        ))

It had to be called from alter_unique_together function of the same module.

So, what you should to do now?

  • Open your database and manually delete the duplicate constraint.
  • Do NOT use the same keys for the constraints.
like image 166
baldr Avatar answered Nov 07 '22 00:11

baldr