gpt4 book ai didi

django - 当已经有ID字段时,如何使UUID字段成为默认字段

转载 作者:行者123 更新时间:2023-12-01 23:07:28 25 4
gpt4 key购买 nike

我正在做一个项目,问题是我已经用简单的ID列创建了模型,但是现在我的要求发生了变化,我想用UUID字段替换ID字段(模型),我刚刚更新了模型:

uuid = models.UUIDField(primary_key=True, default=uuid.uuid4)

但是当我运行迁移时,我得到了一个错误

django.db.utils.OperationalError: (1829, "Cannot drop column 'id': needed in a foreign key constraint



请指导我如何执行此迁移?

最佳答案

这是您需要执行的操作列表
1-将新的uuid字段添加到模型(我将此模型命名为Base),然后生成迁移文件

uuid = models.UUIDField(default=uuid4, blank=True, null=True)


  • 请注意,uuid尚未成为主键
  • 请注意blank = null =True

  • 2-在此步骤中,应使用有效数据填充 uuid字段。您应该为 Base模型编写一个数据迁移文件。请检查 docs了解更多信息
    您的转发方法应如下所示:
    for item in Base.objects.all():
    item.uuid = uuid4()
    item.save()
    3-将uuid字段更改为此并生成迁移

    uuid = models.UUIDField(default=uuid4, unique=True)


  • 请注意,uuid尚未成为主键,但现在是唯一的

  • 4-对于其他指向 Base模型的模型,您应该添加一个指向uuid字段的新外键
    假设您与基本模型的默认关系是这样的
    base = models.ForeignKey(
    Base, on_delete=models.PROTECT, related_name='base'
    )
    您应该添加一个这样的临时字段
    base_uuid = models.ForeignKey(
    Base,
    on_delete=models.PROTECT,
    related_name='base_uuid',
    to_field='uuid',
    blank=True,
    null=True,
    )
  • 注意,我已经明确定义了to_field,它告诉django这个外键没有指向默认的pk字段
  • 您应该保留旧的外键字段
  • 也设置blank = null = True
  • 对于所有指向 Base的外键/manytomanyfield的
  • ,您应该添加此临时字段

  • 5-在此步骤中,您应该创建一个数据迁移文件,
    在此数据迁移文件中,您需要使用有效数据(基于旧的 base_uuid字段)填充所有 base字段,您的迁移代码可以是这样的
    for item in RelatedModel.objects.all():
    item.base_uuid_id = item.base.uuid
  • 此步骤之后,所有模型中的所有base_uuid字段均应包含有效数据

  • 6-在所有相关模型中删除相关字段(保留新的 base_uuid字段但丢弃旧的相关字段)并生成迁移文件
    7-删除所有FK字段上的db_constraint-这是必需的,因为django将通过 base_uuid的唯一约束进行连接,如果我们将 uuid更改为pk,则会删除该约束。
    base_uuid = models.ForeignKey(
    Base,
    on_delete=models.PROTECT,
    related_name='base_uuid',
    to_field='uuid',
    blank=True,
    null=True,
    db_constraint=False
    )
    8-在 Base模型中更改uuid字段并生成迁移文件

    uuid = models.UUIDField(default=uuid4, primary_key=True)


  • uuid现在是主键!

  • 9-在所有相关模型(已添加 base_uuid字段的模型)中更新字段
  • 重命名字段名称(从列名中删除_uuid)(将其设置为个人迁移!)
  • 更改relate_name字段名称(从相关名称中删除_uuid)
  • 如有必要,删除blank = null = true
  • 删除to_field='uuid'参数(不再需要)

  • 非常重要的说明:将这些代码与测试数据一起运行,并从数据库中创建完整备份,然后再对实际数据运行此代码

    关于django - 当已经有ID字段时,如何使UUID字段成为默认字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48200026/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com