为了为模型添加一个新的必填字段 (
null=False
),你需要包含一个默认值。这个默认值将应用于所有现有的记录。
对于
UUIDField
,在迁移期间,Django 不会为每个记录创建一个新的 UUID 值。一个单一的值通过
uuid.uuid4()
生成,并使用单个 SQL 应用于所有记录。因此,如果你在数据库中有现有记录,并且知道
unique=True
是在数据库级别上应用的,那么在迁移期间将出现
IntegrityError
的情况。
如果你需要具有有效 uuid 值的现有记录 (你无法重新创建整个模型迁移与
uuid
字段或者在运行迁移前删除现有的记录),可以使用迁移内的
RunPython
operation 强制为每个记录设置新值。
编辑你的迁移以执行以下步骤:
- 添加一个可空的
uuid
字段,没有 unique
和 default
设置,以便 Django 可以创建该列而不会出现完整性错误。
- 添加自定义 Python 代码以强制现有记录的 uuid
- 更改
uuid
字段,恢复原始设置
import uuid
from django.db import migrations
def force_uuid(apps, schema_editor):
MyModel = apps.get_model('myapp', 'MyModel')
db_alias = schema_editor.connection.alias
for instance in MyModel.objects.using(db_alias).all():
instance.uuid = uuid.uuid4()
instance.save()
class Migration(migrations.Migration):
dependencies = []
operations = [
migrations.AddField(
model_name='mymodel',
name='uuid',
field=models.UUIDField(null=True, unique=False, editable=False),
),
migrations.RunPython(force_uuid),
migrations.AlterField(
model_name='mymodel',
name='uuid',
field=models.UUIDField(
default=uuid.uuid4, null=False, unique=True, editable=False
),
),
]
注意事项