Django 1.9无法修改unique_together(ValueError)错误的约束数

jay*_*ing 6 python django django-migrations

我使用inspectdb创建了我的模型,当django生成以下内容时,它让我感到奇怪,因为只有一个这样的索引,但我让它成为

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

现在我正在尝试将'sku2'添加到此索引中,并且'migrate'失败并显示以下内容:

 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)
Run Code Online (Sandbox Code Playgroud)

这是我的模特:

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',))
Run Code Online (Sandbox Code Playgroud)

我尝试将unique_together更改为(('p_id','v_id','sku',),)和('p_id','v_id','sku'),结果相同.

我也尝试使用数据库手动删除唯一索引并使用django重新创建它,它仍然不会让我添加sku2.

为什么会发生这种情况,我该如何解决?

bal*_*ldr 4

我没有深入挖掘,但检查了一些 Django 1.8 的源代码。我认为这个代码部分是相同的。

我的猜测是您使用此语句创建了错误的约束:

unique_together = (('p_id', 'v_id', 'sku',), ('p_id', 'v_id', 'sku',))
Run Code Online (Sandbox Code Playgroud)

您已创建迁移并应用它。它在数据库中创建了两个相同的约束。从技术上讲这是允许的,但没有意义。

之后,您尝试更改它,但由于 Django 的验证,您收到了错误django.db.backends.base.schema._delete_composed_index()- 它从数据库收集所有约束并验证是否只有一个:

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),
        ))
Run Code Online (Sandbox Code Playgroud)

它必须从alter_unique_together同一模块的函数中调用。

那么,你现在应该做什么?

  • 打开数据库并手动删除重复约束。
  • 不要对约束使用相同的键。