Received "ValueError: Found wrong number (0) of constraints for ..." during Django migration

Received "ValueError: Found wrong number (0) of constraints for ..." during Django migration

在使用 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 与迁移历史不匹配。

如何解决此错误并完成迁移?

(Postgres 和 MySQL 答案)

如果您查看实际的 table(使用 \d table_name)并查看索引,您会找到一个用于唯一约束的条目。这就是 Django 试图找到并丢弃的东西。但是找不到完全匹配的。

例如,

"table_name_...6cf2a9c6e98cbd0d_uniq" UNIQUE CONSTRAINT, btree (d, a, b, c)

在我的例子中,键的顺序 (d, a, b, c) 与它希望删除的约束不匹配 (a, b, c, d)

我回到我的迁移历史并更改了原始 AlterUniqueTogether 以匹配数据库中的 实际 顺序。

迁移随后成功完成。

我在将 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 在那之后没有错误地工作。

同样值得检查的是,对于有问题的 table,您只有预期数量的唯一索引。

例如,如果您的 table 有多个唯一索引,那么您应该删除它们以确保只有 1 个(或任何预期唯一索引的数量)存在迁移前索引。

检查 PostgreSQL 中给定的 table 有多少唯一索引:

SELECT *
FROM information_schema.table_constraints AS c
WHERE
    c.table_name = '<table_name>'
    and c.constraint_type = 'UNIQUE'

以防万一有人遇到这个问题而之前的答案没有解决,在我的情况下,问题是当我修改唯一的一起约束时,尝试了迁移但数据不允许(因为限制性更强的唯一一起约束)。但是,迁移设法从 table 中删除了唯一在一起约束,使其处于不一致状态。我不得不迁移回零并在没有数据的情况下重新应用迁移。然后顺利通过。

总而言之,在应用迁移之前确保您的数据能够接受新约束

"unique_together 在数据库中与迁移历史不匹配" - 每次在 table 上更改索引时,它都会检查其先前的索引并将其删除。在您的情况下,它无法获取以前的索引。

解决方案- 1.Either 可以手动生成 2.Or 恢复到使用先前索引的代码,migrate.Then 最终更改为代码中的新索引并 运行 迁移。(django_migration 个文件需要处理)

  1. 查找各自table的最新迁移文件,查找唯一 在一起,并替换当前的唯一约束字段。
  2. 使用 ./manage.py 迁移数据库 your_app_name.
  3. 还原或撤消以前的迁移文件。

在我的案例中,问题是 table dajsngo_migrations 中没有以前的迁移。我添加了缺失的条目,然后新迁移成功了

有人在修改 unique_together 时可能会遇到此问题。基本上, table 状态与迁移不一致。您可能需要使用 MySQL shell.

手动添加先前的约束