Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django model - changing options in a choices field and migrate

I need to change the name of the options in a model status field, which needs to become

   STATUS = Choices(
    ('option_A', 'Option A'),
    ('option_B', 'Option B'),
   )

Before this change, I had the same options but the names where different. Now I changed everything in the project to respect the new names, but the problem is about updating the database in order to display those new names. I use South for data migrations, and as far as I understand it is fairly straightforward to have it write an automatic migration if you need to add or delete a column in the database but I can't find a way to do this update to my existing column.

I use Django 1.6.

like image 976
mar tin Avatar asked Nov 24 '14 13:11

mar tin


2 Answers

What you're looking for is a datamigration.

$ python manage.py datamigration your_app_label

This will create a new, blank migration in your migration folders. You have to manually create the forwards and backwards methods to change the data how you want it to be:

def forwards(self, orm):
    orm.MyModel.objects.filter(status='old_option_A').update(status='option_A')
    ...

def backwards(self, orm):
    # reverse of forwards, or raise an error to prevent backwards migrations

You'll need to use orm.MyModel instead of directly importing the model for this to work.

Then, simply run the migration:

$ python manage.py migrate your_app_label

Be sure to include both the migration and the change in your options in the same commit in your version control system, so these will always be synced (as long as people remember to migrate on a new version).

like image 140
knbk Avatar answered Sep 28 '22 07:09

knbk


You could write a quick script to make your changes.Something like this:

>>Model.objects.filter(status = "some_old_value").update(status = "new_value")

Where 'status' is field name. You can repeat the above step to change any kind of old values to new values in the same model.

Update() is much faster and shouldn't take long time to run on a moderately sized database https://docs.djangoproject.com/en/dev/topics/db/queries/#updating-multiple-objects-at-once

Also since it would be a one-time script, speed should not be a major issue.

Hope this helps

like image 38
Ymartin Avatar answered Sep 28 '22 07:09

Ymartin