Convert data on AlterField django migration

纵饮孤独 提交于 2019-11-30 14:30:25

Safest way that I always do is:

  1. create another field with field_name_new = models.PositiveIntegerField()
  2. migrate this new field on production db
  3. do data migration (convert field_name value and move the converted value to field field_name_new)
  4. change your code so that field_name_new is used
  5. deploy the step 4
  6. delete the field field_name
  7. migrate the step 6 on production db and deploy it (the step 6)

there is only one bad side: you may loose some data in steps 4 and 5. but you can replicate these data to new field basically

In the past, I've always done this with the help of Djangos RunPython operation. Create a custom migration that handles the following.

  1. Change name of field.
  2. Add new field of desired type.
  3. RunPython to handle the logic of converting from one to the other.
  4. Delete old field.


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 might need to be adjusted, but you get the idea.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!