6

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?

jayshilling
  • 331
  • 2
  • 4
  • 11
  • 1
    By the keyword I can guess you are using `django-south`. Do not use it. It is included in the Django from 1.7. – baldr Dec 21 '15 at 16:39
  • using migrations, i changed it – jayshilling Dec 21 '15 at 16:42
  • Why do you set the constraints twice? – baldr Dec 21 '15 at 16:45
  • i didn't 'inspectdb' produced it such, it seems irrelevant to the problem – jayshilling Dec 21 '15 at 16:46
  • Something wrong with your example.. Model `Products` has one-to-one relation to `Products`? It even won't compile. Please check. – baldr Dec 21 '15 at 18:56
  • fixed, copy/paste oversight – jayshilling Dec 21 '15 at 19:11
  • Everything works fine for me. By the way, where the `v_id` comes from? – baldr Dec 21 '15 at 19:41
  • typo day, s_id=v_id, when i recreate the model under a different name and then try to add 'sku2' it works for me too – jayshilling Dec 21 '15 at 20:16
  • I told you - your database is broken. You may either dump the data and re-create it from scratch or try to fix it by hands. – baldr Dec 21 '15 at 20:23
  • i marked p_id as primary_key in the model after the fact because django needs one... its not a pk in the underlying db, the real pk is composite which django doesnt allow. when we create this model from scratch it actually makes p_id a primary key... which is why it works, that's not an option for me because p_id isn't unique, i think the answer here is basically that Django doesnt allow composite primary kes – jayshilling Dec 22 '15 at 01:07
  • I see. Probably you're right then. You can make either non-managed model and do everything in the database. Or you can make manual migration and fix this in pure SQL. – baldr Dec 22 '15 at 09:45
  • Did you solve this problem? if so, can I have some reference? – aldesabido Jul 08 '16 at 12:19

1 Answers1

4

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.
baldr
  • 2,891
  • 11
  • 43
  • 61
  • as i mentioned i did try to 1) delete this index manually 2) delete it from the model and --fake migrate 3) recreate the index via migration by adding "unique_together = (('p_id', 'v_id', 'sku',)" – jayshilling Dec 21 '15 at 17:40
  • having done that produces the exact same error when i try to add 'sku2' via migrations – jayshilling Dec 21 '15 at 17:41
  • Do you delete old migrations from the `migrations` folder? Maybe it tries to apply old ones? – baldr Dec 21 '15 at 17:43
  • well it says exactly what it's applying when the error occurs... the addition of 'sku2', nothing else – jayshilling Dec 21 '15 at 18:13
  • so i printed consraint_names:[u'products_composite_uniq', u'products_pkey'], the primary key IS the the composite_unique maybe the problem is that Django doesn't support it https://code.djangoproject.com/wiki/MultipleColumnPrimaryKeys – jayshilling Dec 21 '15 at 18:16