Django 和 Postgres 违反外键约束

Foreign Key Constraint Violation with Django and Postgres

当我尝试填充数据时,我发现 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".

查看导致崩溃的具体工作会发现它包含一个 None 专长,因为许多工作没有专长。

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

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

django-modelcluster introduces a new type of relation, ParentalKey, where the related models are stored locally to the ‘parent’ model until the parent is explicitly saved.

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

from modelcluster.fields import ParentalKey

class Job(MongoidModel):
    specialty = ParentalKey(
        Specialty,
        null=True,
        blank=True
     )

约束 "D76699ba021e613d02bad10e8fb41f69" 可能是由 Mongo 库通过错误创建的。没有为 Django 项目使用 MongoDB 我没有很多细节,但是通过 Mongo 本身你可以从数据库中删除约束 "D76699ba021e613d02bad10e8fb41f69" 。据我所知,由于 Mongo 不使用传统的 fk,我假设约束是一个简单的 not-null 并删除它会解决它。

  1. 如果您将数据库切换到 Sqlite3,这是否有效?

  2. 你确定你有 运行 manage.py makemigrations specialtymanage.py migrate 吗?否则,可能存在陈旧的约束。

事实证明,答案在于我创建模型的方式。当我有一位作家以 None 作为他们的专长时,我仍在通过该领域:

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

对象 mapper/object 创建者,django 正在寻找 None 作为专业 table 中的键。正确的做法是检查 specialty_id 是否是 None,然后将其从 mapper/object 创建者中排除:

{'writer_name': 'Bob'}

感谢您的宝贵意见,我学到了很多!