【问题标题】:Received "ValueError: Found wrong number (0) of constraints for ..." during Django migration在 Django 迁移期间收到“ValueError: Found wrong number of (0) of constraint for ...”
【发布时间】: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 不匹配迁移历史记录有关。

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

【问题讨论】:

    标签: django django-migrations


    【解决方案1】:

    有人在修改unique_together 时可能会遇到此问题。基本上,表状态与迁移不一致。您可能需要使用 MySQL shell 手动添加之前的约束。

    【讨论】:

      【解决方案2】:

      在我的情况下,问题是表 dajsngo_migrations 中不存在先前的迁移。我添加了缺少的条目,然后新的迁移工作了

      【讨论】:

      • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
      【解决方案3】:
      1. 找到各自表的最新迁移文件,找到唯一的 一起,并替换当前的唯一约束字段。
      2. 使用 ./manage.py migrate your_app_name 迁移数据库。
      3. 恢复或撤消之前的迁移文件。

      【讨论】:

        【解决方案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 也是如此,我正在使用它
                • 这非常有用,谢谢。实际上帮助我了解了有关迁移如何工作的更多信息 - 即,在反转时回顾以前的迁移。
                猜你喜欢
                • 2020-01-03
                • 1970-01-01
                • 2015-08-19
                • 2021-07-29
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2020-02-16
                • 2018-03-14
                相关资源
                最近更新 更多