问题
I have a production database and need to keep safe the data. I want to change a Field in model and convert all data inside that database with this change.
Old field
class MyModel(models.Model):
field_name = models.TimeField()
Changed field
class MyModel(models.Model):
field_name = models.PositiveIntegerField()
Basically I want to convert the TimeField value (that has a Time object) in minutes.
Example: I have in an object time(hour=2, minute=0, second=0) and I want to convert that field value in all database table to 120 when I apply the migrate.
回答1:
Safest way that I always do is:
- create another field with
field_name_new = models.PositiveIntegerField() - migrate this new field on production db
- do data migration (convert
field_namevalue and move the converted value to fieldfield_name_new) - change your code so that
field_name_newis used - deploy the step 4
- delete the field
field_name - 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
回答2:
In the past, I've always done this with the help of Djangos RunPython operation. Create a custom migration that handles the following.
- Change name of field.
- Add new field of desired type.
- RunPython to handle the logic of converting from one to the other.
- 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.
来源:https://stackoverflow.com/questions/39628637/convert-data-on-alterfield-django-migration