[Answer]-Modify a model field's data using South

1👍

✅

For this, you’ll have to create a data migration

# Run this command from the shell
python manage.py datamigration <app_name> change_foo_values

This is will create a migration file named 0003_change_foo_values.py. You will have to manually edit the file.

# -*- coding: utf-8 -*-
from south.utils import datetime_utils as datetime
from south.db import db
from south.v2 import DataMigration
from django.db import models

class Migration(DataMigration):

    def forwards(self, orm):
        "Write your forwards methods here."
        # Note: Don't use "from appname.models import ModelName". 
        # Use orm.ModelName to refer to models in this application,
        # and orm['appname.ModelName'] for models in other applications.
        orm.Applicant.objects.filter(foo__in=['1', '2']).update(foo='1')
        orm.Applicant.objects.filter(foo__in=['3', '4']).update(foo='2')
        orm.Applicant.objects.filter(foo__in=['5', '6']).update(foo='3')

    def backwards(self, orm):
        "Write your backwards methods here."

         # This migration cannot be reversed
         pass    # don't do anything when running reverse migration
         # or
         raise RuntimeError("Cannot reverse this migration") # stop south from reverting beyond this migration

Note: You won’t be able to go revert back to the previous values of the column. If that is not a problem then this is sufficient.

However, if you do want to be able to reverse the migration, I suggest creating a new field, that will hold the old value of the column for each row.

PS: Your migration files seem wrong. You should not have two initial migrations for one app. Did you run convert_to_south after renaming your model(which doesn’t seem to have been renamed) again? You only need to run convert_to_south once, when initially converting an existing model to south. After that you need to create schema migrations. The simplest way would be to run the schemamigration management command with the appname, and --auto as arguments.

python manage.py schemamigration <app_name> --auto

PPS: If you want to rename a model, please create an empty migration and write the migration code yourself, just use db.rename_table. IIRC south will delete your old table before creating a new one if you try to create auto schemamigrations after renaming the model.

python manage.py schemamigration <app_name> --empty rename_model_x_to_y

And in your migration file

# -*- coding: utf-8 -*-
from south.utils import datetime_utils as datetime
from south.db import db
from south.v2 import DataMigration
from django.db import models

class Migration(SchemaMigration):

    def forwards(self, orm):
        "Write your forwards methods here."
        # Note: Don't use "from appname.models import ModelName". 
        # Use orm.ModelName to refer to models in this application,
        # and orm['appname.ModelName'] for models in other applications.
        db.rename_table('old', 'new')

    def backwards(self, orm):
        "Write your backwards methods here."
        db.rename_table('new', 'old')

Leave a comment