在 Django 迁移期间收到“ValueError: Found wrong number of (0) of constraint for ...”
Posted
技术标签:
【中文标题】在 Django 迁移期间收到“ValueError: Found wrong number of (0) of constraint for ...”【英文标题】:Received "ValueError: Found wrong number (0) of constraints for ..." during Django migration 【发布时间】:2017-05-28 04:05:34 【问题描述】:在使用 Django 1.7 迁移时,我遇到了一个在开发中有效但在生产中无效的迁移:
ValueError: Found wrong number (0) of constraints for table_name(a, b, c, d)
这是由AlterUniqueTogether
规则引起的:
migrations.AlterUniqueTogether(
name='table_name',
unique_together=set([('a', 'b')]),
)
阅读 Django 错误数据库中的错误等,似乎与数据库中现有的 unique_together
不匹配迁移历史记录有关。
如何解决此错误并完成我的迁移?
【问题讨论】:
【参考方案1】:有人在修改unique_together
时可能会遇到此问题。基本上,表状态与迁移不一致。您可能需要使用 mysql shell 手动添加之前的约束。
【讨论】:
【参考方案2】:在我的情况下,问题是表 dajsngo_migrations 中不存在先前的迁移。我添加了缺少的条目,然后新的迁移工作了
【讨论】:
您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。【参考方案3】:-
找到各自表的最新迁移文件,找到唯一的
一起,并替换当前的唯一约束字段。
使用 ./manage.py migrate your_app_name 迁移数据库。
恢复或撤消之前的迁移文件。
【讨论】:
【参考方案4】:“数据库中的unique_together 与迁移历史不匹配” - 每次更改表上的索引时,它都会检查其先前的索引并将其删除。在您的情况下,它无法获取以前的索引。
解决方案- 1.您可以手动生成它 2.或者恢复到使用先前索引的代码并迁移。然后最后在代码中更改为新索引并运行迁移。(要处理的django_migration文件)
【讨论】:
【参考方案5】:以防万一有人遇到此问题并且之前的答案尚未解决,在我的情况下,问题是当我修改唯一共同约束时,尝试迁移但数据不允许它(因为更严格的唯一一起约束)。但是,迁移设法从表中删除了唯一的共同约束,使其处于不一致的状态。我不得不迁移回零并在没有数据的情况下重新应用迁移。然后就顺利通过了。
总之,请确保您的数据在应用迁移之前能够接受新的约束。
【讨论】:
【参考方案6】:另外值得检查的是,您只有预期数量的相关表的唯一索引。
例如,如果您的表有多个唯一索引,那么您应该删除它们以确保只有 1 个(或任何预期的唯一索引数量)存在迁移前索引。
检查 PostgreSQL 中给定表有多少唯一索引:
SELECT *
FROM information_schema.table_constraints AS c
WHERE
c.table_name = '<table_name>'
and c.constraint_type = 'UNIQUE'
【讨论】:
【参考方案7】:我在将 CharField 切换为 ForeignKey 时遇到了类似的问题。一切都与这个过程一起工作,但我留下 Django 认为它仍然需要在新的迁移中更新unique_together
。 (即使从 postgres 内部看起来一切都是正确的。)不幸的是,应用这个新迁移会产生类似的错误:
ValueError: Found wrong number (0) of constraints for program(name, funder, payee, payer, location, category)
最终对我有用的解决方法是注释掉该模型之前的所有 AlterUniqueTogether
操作。之后manage.py migrate
正常工作。
【讨论】:
【参考方案8】:(Postgres 和 MySQL 答案)
如果您查看您的实际表(使用\d table_name
)并查看索引,您会发现您的唯一约束的条目。这就是 Django 试图寻找和放弃的东西。但它找不到完全匹配的。
例如,
"table_name_...6cf2a9c6e98cbd0d_uniq" UNIQUE CONSTRAINT, btree (d, a, b, c)
在我的例子中,键 (d, a, b, c)
的顺序与它希望删除的约束 (a, b, c, d)
不匹配。
我回到了我的迁移历史并更改了原来的 AlterUniqueTogether
以匹配数据库中的实际顺序。
然后迁移成功完成。
【讨论】:
非常感谢分享这个。我正在使用 MySQL,并且在 DB 约束中的字段顺序与添加 unique_together 的原始迁移文件中的字段顺序不匹配时遇到了同样的问题。 我认为我会很棘手,将进行两次迁移:删除现有约束,然后添加新的扩展约束。但是由于这个错误,即使删除也不成功,所以我需要重新排序。 :P 哦,这对 MySQL 也是如此,我正在使用它 这非常有用,谢谢。实际上帮助我了解了有关迁移如何工作的更多信息 - 即,在反转时回顾以前的迁移。以上是关于在 Django 迁移期间收到“ValueError: Found wrong number of (0) of constraint for ...”的主要内容,如果未能解决你的问题,请参考以下文章