当已经有ID字段时,如何使UUID字段成为默认字段 [英] How to make UUID field default when there's already ID field
问题描述
我正在处理一个项目,问题是我已经用简单的ID列创建了模型,但是现在我的要求已更改,我想用UUID字段替换ID字段(模型),我刚刚更新了模型:>
I'm working on a project and problem is I've already created models with simple ID column but now my requirements are changed and I want to replace ID field (model) with UUID field I just updated my model:
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4)
但是当我运行迁移时,我得到了一个错误
but when I run my migrations I got an error
django.db.utils.OperationalError :( 1829,无法删除列'id':外键约束中需要的
django.db.utils.OperationalError: (1829, "Cannot drop column 'id': needed in a foreign key constraint
请指导我如何执行此迁移?
Please guide me how can I perform this migration?
推荐答案
这是您需要执行的操作列表
here are the list of actions that you need to do
1-将新的 uuid
字段添加到模型中(我将此模型命名为 Base
),然后生成迁移文件
1 - add the new uuid
field to model (I name this model Base
) then generate migration files
uuid = models.UUIDField(默认= uuid4,空白=真,null =真)
uuid = models.UUIDField(default=uuid4, blank=True, null=True)
- 请注意,uuid还不是主键
- 请注意,
blank = null = True
2-在此步骤中,应使用有效数据填充 uuid
字段.您应该为 Base
模型编写一个数据迁移文件.请查看文档以获取更多信息
2- in this step you should populate uuid
field with valid data. you should write a data migration file for Base
model. please check docs for more info
您的转发方法应如下所示:
your forwards method should be something like this:
for item in Base.objects.all():
item.uuid = uuid4()
item.save()
3-将此字段更改为uuid并生成迁移
3- change uuid field to this and generate migrations
uuid = models.UUIDField(默认= uuid4,唯一=真)
uuid = models.UUIDField(default=uuid4, unique=True)
- 请注意,uuid尚不是主键,但现在是唯一的
4-对于其他指向 Base
模型的模型,您应该添加一个指向uuid字段的新外键
4 - for other models which are pointing to Base
model you should add a new foreignkey pointing to uuid field
假设您与基本模型的默认关系是这样的
assumig your default relation to Base model is something like this
base = models.ForeignKey(
Base, on_delete=models.PROTECT, related_name='base'
)
您应该添加一个这样的临时字段
you should add a temprory field like this
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,您应添加此临时字段 - note that I have explicitly defined
to_field
which tell django this foreign key is not pointing to defaultpk
field - you should keep old foreign key field
- also set
blank = null = True
- for all foreignkeys/manytomanyfield pointing to
Base
you should add this temp field - 此步骤之后,所有模型中的所有
base_uuid
字段均应包含有效数据 - after this step all
base_uuid
fields in all models should contain a valid data
5-在此步骤中,您应该创建一个数据迁移文件,
5- in this step you should create a data migration file,
在此数据迁移文件中,您需要使用有效数据(基于旧的 base
字段)填充所有 base_uuid
字段,您的迁移代码可以是这样的
in this data migration file you need to fill all base_uuid
fields with valid data (based on old base
field) your migration code can be something like this
用于RelatedModel.objects.all()中的项目:item.base_uuid_id = item.base.uuid
6-在所有相关模型中删除相关字段(保留新的 base_uuid
字段,但丢弃旧的相关字段)并生成迁移文件
6- in all related models drop related field (keep the new base_uuid
field but discard old related field) and generate a migration file
7-删除所有FK字段上的db_constraint-这是必需的,因为django将通过 base_uuid
的唯一约束进行连接,如果将 uuid
更改为PK.
7- delete the db_constraint on all FK fields - this is needed, because django will connect through the unique constraint from base_uuid
which will be dropped if we change uuid
to 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字段并生成迁移文件
8- in Base
model change uuid field and generate a migration file
uuid = models.UUIDField(默认= uuid4,primary_key = True)
uuid = models.UUIDField(default=uuid4, primary_key=True)
- uuid现在是主键!
- 重命名字段名称(从列名称中删除
_uuid
)(将其设为单个迁移!) - 更改
relate_name
字段名称(从相关名称中删除_uuid
) - 如有必要,删除
blank = null = true
- 删除
to_field ='uuid'
参数(不再需要此参数) - rename field name (remove
_uuid
from column name) (make this a individual Migration!) - change
relate_name
field name (remove_uuid
from related name) - remove
blank = null = true
if necessary - remove
to_field='uuid'
argument (you don't need that any more)
9-在所有相关模型(已添加 base_uuid
字段的模型)中更新字段
9- in all related models (models which you have added base_uuid
fields) update the field
非常重要的提示::在测试数据上运行这些代码并从数据库创建完整备份,然后再对实际数据运行此代码
Very Important Note: run these code with test data and create a full backup from your database before running this code on your actual data
这篇关于当已经有ID字段时,如何使UUID字段成为默认字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!