繁体   English   中英

Django IntegrityError更改外键

[英]Django IntegrityError changing a ForeignKey

我有一个模型LucyGuide通过一个OneToOneField扩展了Django的User模型:

class LucyGuide(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)

还有一个Company模型,其中有一个名为lucy_guide的字段,该字段是User模型的ForeignKey

class Company(models.Model):
    lucy_guide = models.ForeignKey(User)

我想将其更改为

class Company(models.Model):
    lucy_guide = models.ForeignKey(LucyGuide)

但是,当我实施此更改并进行并运行迁移时,遇到了IntegrityError

django.db.utils.IntegrityError: insert or update on table "lucy_web_company" violates foreign key constraint "lucy_web_company_lucy_guide_id_de643702_fk_lucy_web_"
DETAIL:  Key (lucy_guide_id)=(461) is not present in table "lucy_web_lucyguide".

这个问题类似于IntegrityError,对表“ orders_order”的插入或更新违反了“外键约束” ;似乎我已经在LucyGuide它们引用为外键之前创建了LucyGuide对象。

解决此问题的最佳方法是什么? 我需要在Shell中编写一系列命令来创建这些用户吗?

更新

从外壳LucyGuide ,似乎Django仍然期望ForeignKey拥有相同的数字id ,即使模型已更改(从UserLucyGuide )。 这是Userids ,它们也是LucyGuideids

In [11]: lucy_guide_users = [user for user in User.objects.all() if hasattr(user, 'lucyguide')]

In [16]: [user.id for user in lucy_guide_users]
Out[16]: [12, 8, 461, 497, 500, 471, 475, 495]

请注意,它包含来自错误的461id 但是, LucyGuideid只是

In [17]: [guide.id for guide in LucyGuide.objects.all()]
Out[17]: [1, 2, 3, 4, 5, 6, 7, 8]

解决此问题的方法似乎是更改LucyGuide的主键,但是从现有Django应用程序中更改主键的最佳方法看来是什么? 这是一个非常复杂的过程。 有没有更简单的方法?

您不能简单地更改外键的目标。 对于每个现有公司,您需要将lucy_guide_id从相关用户的ID更改为相关lucy_guide的ID。 Django无法为您做到这一点。

您可以分几个步骤进行迁移。 首先,添加新的外键并创建迁移

class Company(models.Model):
    lucy_guide = models.ForeignKey(User)
    new_lucy_guide = models.ForeignKey(LucyGuide, blank=True, null=True)

接下来,创建数据迁移以填充new_lucy_guide字段。

然后,您可以删除lucy_guide字段,并创建迁移。

class Company(models.Model):
    new_lucy_guide = models.ForeignKey(LucyGuide, blank=True, null=True)

最后,您可以重命名字段并创建迁移:

class Company(models.Model):
    lucy_guide = models.ForeignKey(LucyGuide, blank=True, null=True)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM