Django现有项目添加带uuid4默认值唯一字段如何简化迁移流程?
问题根源
Django 4.2以下版本,给已存在数据的表新增带可调用默认值的唯一字段时,迁移操作只会调用一次默认函数生成固定值,所有已有行都会复用这个值,自然触发唯一约束冲突。
无需自定义迁移的解决方法
方案1:升级到Django 4.2及以上版本(成本最低)
升级后直接使用你最开始的字段定义即可,不需要任何额外修改:
internal_code = models.CharField(max_length=128, default=uuid.uuid4, unique=True)
正常执行makemigrations和migrate命令,Django会自动为每一行单独调用uuid.uuid4()生成唯一值,不会出现重复报错。
方案2:使用数据库层面默认值(适配Django 3.2及以上版本)
如果暂时无法升级Django大版本,可以用数据库原生的UUID生成函数作为字段的数据库默认值,一步完成迁移,不需要编写自定义迁移逻辑:
PostgreSQL 数据库
from django.db import models import uuid from django.db.models.functions import RandomUUID internal_code = models.UUIDField( default=uuid.uuid4, unique=True, db_default=RandomUUID() )
MySQL 8.0+ 数据库
from django.db import models import uuid internal_code = models.UUIDField( default=uuid.uuid4, unique=True, db_default=models.Func(function='UUID') )
如果需要保持字段为CharField类型,只需要把字段类型改回CharField(max_length=128)即可,其余配置不变。
定义完成后直接执行迁移命令,数据库会自动为所有已有行生成唯一UUID,完全不需要自定义RunPython逻辑。
内容的提问来源于stack exchange,提问作者Milano
相关产品推荐
相关产品推荐

