在 AlterField django 迁移上转换数据
Convert data on AlterField django migration
我有一个生产数据库,需要保护数据安全。我想更改模型中的字段并使用此更改转换该数据库中的所有数据。
旧字段
class MyModel(models.Model):
field_name = models.TimeField()
更改字段
class MyModel(models.Model):
field_name = models.PositiveIntegerField()
基本上我想以分钟为单位转换 TimeField 值(具有 Time 对象)。
示例:我有一个对象 time(hour=2, minute=0, second=0)
,我想在应用迁移时将所有数据库 table 中的该字段值转换为 120
。
我一直做的最安全的方法是:
- 使用
field_name_new = models.PositiveIntegerField()
创建另一个字段
- 将这个新字段迁移到生产数据库
- 进行数据迁移(转换
field_name
值并移动
将值转换为字段 field_name_new
)
- 更改代码以便使用
field_name_new
- 部署步骤 4
- 删除字段
field_name
- 在生产数据库上迁移第 6 步并部署它(第 6 步)
只有一个不好的方面:您可能会在第 4 步和第 5 步中丢失一些数据。但是您基本上可以将这些数据复制到新字段
以前都是借助Djangos RunPython操作完成的。创建处理以下内容的自定义迁移。
- 更改字段名称。
- 添加所需类型的新字段。
- 运行 Python 来处理从一个到另一个的转换逻辑。
- 删除旧字段。
def migrate_time_to_positive_int(apps, schema_editor):
MyModel = apps.get_model('myapp', 'MyModel')
for mm in MyModel.objects.all():
field_old_time = mm.field_name_old
field_new_int = field_old_time.total_seconds() / 60
mm.field_name = field_new_int
mm.save()
class Migration(migrations.Migration):
operations = [
migrations.RenameField(
model_name='mymodel',
old_name='field_name',
new_name='field_name_old',
),
migrations.AddField(
model_name='mymodel',
name='field_name',
field=models.PositiveIntegerField(),
),
migrations.RunPython(migrate_time_to_positive_int),
migrations.RemoveField(
model_name='mymodel',
name='field_name_old',
)
]
field_name_old.total_seconds() / 60 可能需要调整,但你明白了。
我有一个生产数据库,需要保护数据安全。我想更改模型中的字段并使用此更改转换该数据库中的所有数据。
旧字段
class MyModel(models.Model):
field_name = models.TimeField()
更改字段
class MyModel(models.Model):
field_name = models.PositiveIntegerField()
基本上我想以分钟为单位转换 TimeField 值(具有 Time 对象)。
示例:我有一个对象 time(hour=2, minute=0, second=0)
,我想在应用迁移时将所有数据库 table 中的该字段值转换为 120
。
我一直做的最安全的方法是:
- 使用
field_name_new = models.PositiveIntegerField()
创建另一个字段
- 将这个新字段迁移到生产数据库
- 进行数据迁移(转换
field_name
值并移动 将值转换为字段field_name_new
) - 更改代码以便使用
field_name_new
- 部署步骤 4
- 删除字段
field_name
- 在生产数据库上迁移第 6 步并部署它(第 6 步)
只有一个不好的方面:您可能会在第 4 步和第 5 步中丢失一些数据。但是您基本上可以将这些数据复制到新字段
以前都是借助Djangos RunPython操作完成的。创建处理以下内容的自定义迁移。
- 更改字段名称。
- 添加所需类型的新字段。
- 运行 Python 来处理从一个到另一个的转换逻辑。
- 删除旧字段。
def migrate_time_to_positive_int(apps, schema_editor):
MyModel = apps.get_model('myapp', 'MyModel')
for mm in MyModel.objects.all():
field_old_time = mm.field_name_old
field_new_int = field_old_time.total_seconds() / 60
mm.field_name = field_new_int
mm.save()
class Migration(migrations.Migration):
operations = [
migrations.RenameField(
model_name='mymodel',
old_name='field_name',
new_name='field_name_old',
),
migrations.AddField(
model_name='mymodel',
name='field_name',
field=models.PositiveIntegerField(),
),
migrations.RunPython(migrate_time_to_positive_int),
migrations.RemoveField(
model_name='mymodel',
name='field_name_old',
)
]
field_name_old.total_seconds() / 60 可能需要调整,但你明白了。