【问题标题】:Foreign Key Constraint Violation with Django and PostgresDjango 和 Postgres 违反外键约束
【发布时间】:2015-07-15 18:48:53
【问题描述】:

当我尝试填充数据时,我在 Django 1.7 中的两个模型之间遇到外键约束冲突。

第一个模型是Specialty,一个简单的名称占位符,看起来像这样:

class Specialty(MongoidModel):
    name = models.CharField(max_length=100)

引用它的模型 Job 如下所示:

class Job(MongoidModel):
    specialty = models.ForeignKey(
        Specialty,
        null=True,
        blank=True
     )

这两个都继承了 MongoidModel,它只是一个自定义模型,包含一个 id、一个 created_at 日期和一个 updated_at 日期,用于从原始 Mongo 数据库中移植数据。

Makemigrations 和 migrate 一样运行良好,但是当我实际尝试移植所有 Job 对象时,我立即收到此错误:

django.db.utils.IntegrityError: insert or update on table "jobs_job" 
violates foreign key constraint "D76699ba021e613d02bad10e8fb41f69"
DETAIL:  Key (specialty_id)=(None) is not present in table
"specializations_specialty".

查看导致崩溃的特定工作会发现它包含专业的无,因为许多工作没有专业。

据我了解,数据库正在尝试查找 ID 为 None 的特殊对象,但失败了。我认为这就是 ForeignKey 定义中的 blank=True 和 null=True 应该优雅地避免,不让它进入那种状态,只是让关联撒谎?

【问题讨论】:

    标签: django mongodb postgresql migration


    【解决方案1】:

    如果尝试通过覆盖的模型或管理员保存方法保存相关模型,可能会收到类似的错误。如果没有看到您的完整模型或管理代码,这只是在黑暗中刺伤,但 django-modelcluster 可能会提供您需要的级联保存结构。

    django-modelcluster 引入了一种新的关系类型 ParentalKey,其中相关模型存储在本地 'parent' 模型,直到显式保存父级。

    要使用它,请导入 ParentalKey 模型字段类型并像 FK 一样使用它。

    from modelcluster.fields import ParentalKey
    
    class Job(MongoidModel):
        specialty = ParentalKey(
            Specialty,
            null=True,
            blank=True
         )
    

    可能存在约束“D76699ba021e613d02bad10e8fb41f69”是由 Mongo 库通过错误创建的。没有将 MongoDB 用于 Django 项目我没有太多详细信息,但是通过 Mongo 本身,您可以从 db 中删除约束“D76699ba021e613d02bad10e8fb41f69”。据我所知,由于 Mongo 不使用传统的 fk,我假设约束是一个简单的非空,删除它会解决它。

    【讨论】:

      【解决方案2】:
      1. 如果您将数据库切换到 Sqlite3,这是否有效?

      2. 你确定你已经运行了manage.py makemigrations specialtymanage.py migrate?否则,可能会有过时的约束。

      【讨论】:

        【解决方案3】:

        事实证明,答案在于我创建模型的方式。当我有一个作家进来时,他们的专长是无,我还在通过那个领域:

        {'writer_name': 'Bob', 'specialty_id':None} 
        

        到对象映射器/对象创建者,django 正在寻找一个 None 作为 Specialty 表中的键。正确的做法是检查 special_id 是否为 None,然后将其从映射器/对象创建器中排除:

        {'writer_name': 'Bob'}
        

        感谢cmets的帮助,我学到了很多!

        【讨论】:

          猜你喜欢
          • 2021-02-14
          • 2017-09-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-06-20
          • 2019-03-20
          相关资源
          最近更新 更多