【问题标题】:Django migration fails with InvalidForeignKey: "unique constraint" error for "django_site"Django 迁移因 InvalidForeignKey 失败:“django_site”的“唯一约束”错误
【发布时间】:2021-09-07 09:31:34
【问题描述】:

我遇到了 django 迁移问题。如果您知道如何解决此问题,请提供帮助!

我将 Django 从 2.2.7 升级到 3.2。在新系统中我继续工作,添加了一些新模型。我添加了一个名为“Space”的新模型,它与 Django Site 模型具有一对一的关系。这一切都适用于我的开发机器(PostgreSQL 9.6)和登台机器(PostgreSQL 9.4,尽管我不得不解决与 Django 3.2 的轻微不兼容问题)。

但是,在生产环境中,我们已从旧版本的 PostgreSQL 9.4 升级到 PostreSQL 12。现在迁移将无法运行!它给出了以下错误:

Running migrations:
  Applying appname.0039_auto_20210521_1034...Traceback (most recent call last):
  File "/data/virtualenvs/appname/lib/python3.9/site-packages/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
psycopg2.errors.InvalidForeignKey: there is no unique constraint matching given keys for referenced table "django_site"

这是迁移文件 0039_auto_20210521_1034 中一定会导致问题的部分...?

migrations.CreateModel(
            name='Space',
            fields=[
                ('site', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True, related_name='spaces', serialize=False, to='sites.Site', verbose_name='site')),
                ('virtual', models.BooleanField(blank=True, default=False)),
            ],
        ),

模型如下所示:

class Space(models.Model):
    """Space model is OneToOne related to Site model."""
    site = models.OneToOneField(
        Site, on_delete=models.CASCADE, primary_key=True,
        related_name='space', verbose_name='site')

    virtual = models.BooleanField(null=False, blank=True, default=False,
                                  help_text="The kind of space that events take place in.")

有人知道发生了什么吗?

提前感谢您的帮助,我需要它!

【问题讨论】:

  • 由于site 是唯一的,您只能最多创建一个指向同一个Site 的链接,而不是两个或更多。

标签: python django postgresql django-migrations


【解决方案1】:

如果其他人发现这一点,关键是简单地列出约束

SELECT con.oid, con.conname, con.connamespace, con.contype
       FROM pg_catalog.pg_constraint con
            INNER JOIN pg_catalog.pg_class rel
                       ON rel.oid = con.conrelid
            INNER JOIN pg_catalog.pg_namespace nsp
                       ON nsp.oid = connamespace
       WHERE nsp.nspname = 'playaevents'
             AND rel.relname = 'django_site';

原始数据库返回两行,副本返回0行。

【讨论】:

    【解决方案2】:

    事实证明,不知何故,我正在使用的数据库副本神秘地失去了对该表的约束(可能还有其他表,我没有检查其他表)。

    我没有执行数据库复制,所以我不知道这是怎么发生的。如果有人有理论,请告诉。

    但就我而言,这解决了问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-22
      • 1970-01-01
      • 2018-01-05
      • 1970-01-01
      • 2015-04-24
      • 1970-01-01
      • 2022-01-21
      • 1970-01-01
      相关资源
      最近更新 更多