Django:将FK关系添加到现有模型

Django:将FK关系添加到现有模型,django,Django,我有一个项目,我需要将一个普通字段更改为FK字段,并在多个模型中更改。 问题是项目是有生产力的,数据库(Postgres)中充满了条目 我从本地开始,只是无意识地将字段类型更改为forgein_key(),并尝试进行迁移。Django似乎非常聪明,他试图更新这个字段,但由于模型中的值在相关模型中不存在,所以他失败了。如何跳过这些错误?如果相关条目不存在,我可以告诉Django将FK==null设置吗 下面是一些代码: from persons.models import Customer, Em

我有一个项目,我需要将一个普通字段更改为FK字段,并在多个模型中更改。 问题是项目是有生产力的,数据库(Postgres)中充满了条目

我从本地开始,只是无意识地将字段类型更改为forgein_key(),并尝试进行迁移。Django似乎非常聪明,他试图更新这个字段,但由于模型中的值在相关模型中不存在,所以他失败了。如何跳过这些错误?如果相关条目不存在,我可以告诉Django将FK==null设置吗

下面是一些代码:

from persons.models import Customer, Employee

class Insurance(models.Model):
    id = models.BigAutoField(primary_key=True)
    customer = models.ForeignKey(Customer, models.SET_NULL, blank=True, null=True)
    employee_id = ForeignKey(Customer, models.SET_NULL, blank=True, null=True)
    objects = models.Manager()

在后端代码中创建字符字段和关系的字段之前。我尝试这样做的原因是我需要Django提供的功能,如select/prefech_,用于前端保险表中的搜索功能。用户还可以选择搜索被保险人的姓名,而不仅仅是身份证

这是由于不存在条目而导致的错误:

django.db.utils.IntegrityError: insert or update on table "insurance_insurance" violates foreign key constraint "insurance_insur_customer_id_98e84761_fk_person_"
DETAIL:  Key (customer_id)=(100883) is not present in table "person_customer".

有谁能告诉我一个可靠的更安全的方法来建立这些关系吗


提前谢谢

您可以执行以下步骤:

1) 使用FK复制文件

class Insurance(models.Model):
    id = models.BigAutoField(primary_key=True)
    customer = models.CharField()
    employee_id = models.CharField()
    customer_new = models.ForeignKey(Customer, models.SET_NULL, blank=True, null=True)
    employee_id_new = ForeignKey(Customer, models.SET_NULL, blank=True, null=True)
    objects = models.Manager()
2) 创建脚本以将数据作为ForeignKey从旧字段迁移到新字段

3) 删除旧字段

class Insurance(models.Model):
    id = models.BigAutoField(primary_key=True)
    customer_new = models.ForeignKey(Customer, models.SET_NULL, blank=True, null=True)
    employee_id_new = ForeignKey(Customer, models.SET_NULL, blank=True, null=True)
    objects = models.Manager()
4) 重命名新字段

class Insurance(models.Model):
    id = models.BigAutoField(primary_key=True)
    customer = models.ForeignKey(Customer, models.SET_NULL, blank=True, null=True)
    employee_id = ForeignKey(Customer, models.SET_NULL, blank=True, null=True)
    objects = models.Manager()
附笔。
不要忘记在每次迁移之前进行DB备份,以便在出现问题时回滚。

在将
IntegerField
(?)转换为
ForeignKey
之前,您可能应该这样做。首先,我们可以使
整型字段
为空:

class Insurance(models.Model):
    id = models.BigAutoField(primary_key=True)
    customer = models.IntegerField(null=True, db_column='customer_id')
    employee_id = ForeignKey(Customer, models.SET_NULL, blank=True, null=True)
您可以进行单独的迁移,也可以将此迁移功能添加到通过模型更改构建的迁移文件中

接下来,我们可以将列的类型更改为
ForeignKey

class Insurance(models.Model):
    id = models.BigAutoField(primary_key=True)
    customer = models.ForeignKey(Customer, null=True, db_column='customer_id')
    employee_id = ForeignKey(Customer, models.SET_NULL, blank=True, null=True)
类别保险(models.Model):
id=models.BigAutoField(主键=True)
customer=models.ForeignKey(customer,null=True,db\u column='customer\u id')

employee_id=ForeignKey(Customer,models.SET_NULL,blank=True,NULL=True)
该查询对我不起作用。但感谢您对数据迁移的提示。事实上,正如您所建议的那样,将我的无效fk设置为NULL的部分,就是第一个答案的解决方案。现在可以工作了,谢谢!
from django.db.models import Q

def set_invalid_customers_to_null(apps, schema_editor):
    Customer = apps.get_model('app', 'Customer')
    Insurance = apps.get_model('app', 'Insurance')
    Insurance.objects.filter(
        ~Q(customer__in=Customer.objects.values_list('pk', flat=True))
    ).update(customer=None)
class Insurance(models.Model):
    id = models.BigAutoField(primary_key=True)
    customer = models.ForeignKey(Customer, null=True, db_column='customer_id')
    employee_id = ForeignKey(Customer, models.SET_NULL, blank=True, null=True)