如何在Django的Bar模型新增字段并从关联Foo模型迁移数据?
Django模型字段迁移:将Foo的status移至Bar并同步数据
步骤1:给Bar模型添加status字段
先在Bar模型中新增status字段,为避免已有数据导致迁移报错,先设置允许为空(数据同步完成后可改为非空):
class Bar(models.Model): foo = models.ForeignKey(to=Foo, on_delete=models.CASCADE) status = models.PositiveSmallIntegerField(verbose_name=_('status'), null=True) ...
步骤2:生成添加字段的迁移文件
执行命令生成迁移:
python manage.py makemigrations
步骤3:编写数据迁移脚本同步数据
编辑刚生成的迁移文件(比如your_app/migrations/00XX_add_status_to_bar.py),添加数据同步逻辑:
from django.db import migrations from django.db.models import F def migrate_status_from_foo_to_bar(apps, schema_editor): # 使用历史模型,避免当前模型变更影响迁移 Bar = apps.get_model('your_app_name', 'Bar') # 批量同步,比循环单个保存更高效 Bar.objects.update(status=F('foo__status')) class Migration(migrations.Migration): dependencies = [ ('your_app_name', '00XX_previous_migration'), # 替换为实际依赖的迁移编号 ] operations = [ migrations.AddField( model_name='bar', name='status', field=models.PositiveSmallIntegerField(null=True, verbose_name=_('status')), ), # 新增数据同步操作 migrations.RunPython(migrate_status_from_foo_to_bar), ]
提示:如果需要对status做额外逻辑处理,再改为循环单个
Bar对象保存;数据量较大时,优先用批量更新。
步骤4:移除Foo模型的status字段
直接删除Foo模型中的status字段:
class Foo(models.Model): ... # 移除原status字段行 ...
步骤5:生成移除字段的迁移文件
再次执行生成迁移命令:
python manage.py makemigrations
步骤6:执行所有迁移
最后运行迁移,完成整个字段迁移和数据同步:
python manage.py migrate
注意事项
- 操作前务必备份数据库,防止数据丢失
- 建议先在测试环境验证流程,确认无误后再在生产环境执行
- 若后续需要
Bar的status字段为非空,可在数据同步完成后,修改模型去掉null=True,再生成并执行迁移
内容的提问来源于stack exchange,提问作者Mohammad Goodarzi
相关产品推荐
相关产品推荐

