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.
Migrations are Django's way of propagating changes you make to your models (adding a field, deleting a model, etc.) into your database schema. They're designed to be mostly automatic, but you'll need to know when to make migrations, when to run them, and the common problems you might run into.
By doing python manage.py migrate app B (or A; both works) . Remove the migration files A and Y for time being from the project location. Now unapply B, by doing python manage.py migrate app X .
To recap, the basic steps to use Django migrations look like this: Create or update a model. Run ./manage.py makemigrations <app_name> Run ./manage.py migrate to migrate everything or ./manage.py migrate <app_name> to migrate an individual app.
So the difference between makemigrations and migrate is this: makemigrations auto generates migration files containing changes that need to be applied to the database, but doesn't actually change anyhting in your database. migrate will make the actual modifications to your database, based on the migration files.
In the past, I've always done this with the help of Djangos RunPython operation. Create a custom migration that handles the following.
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.
Safest way that I always do is:
field_name_new = models.PositiveIntegerField()
field_name
value and move the
converted value to field field_name_new
)field_name_new
is usedfield_name
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With