migrating django-model field-name change without losing data

Changing the field name while keeping the DB field

Adding an answer for Django 1.8+ (with Django-native migrations, rather than South).

Make a migration that first adds a db_column property, and then renames the field. Django understands that the first is a no-op (because it changes the db_column to stay the same), and that the second is a no-op (because it makes no schema changes). I actually examined the log to see that there were no schema changes...

operations = [
    migrations.AlterField(
        model_name='mymodel',
        name='oldname',
        field=models.BooleanField(default=False, db_column=b'oldname'),
    ),
    migrations.RenameField(
        model_name='mymodel',
        old_name='oldname',
        new_name='newname',
    ),
]

Django 2.0.9 (and onwards) can automatically detect if a field was renamed and gives an option to rename instead of delete and create a new one

(same works for Django 2.2) enter image description here

Initial answer

Posting, if it's still helpful for someone.

For Django 2.0 + simply rename the field in the model

class Foo(models.Model):
    orig_name = models.CharField(max_length=50)

to

class Foo(models.Model):
    name = models.CharField(max_length=50)

Now run python manage.py makemigrations It'll generate migration with operations for removing the old field and adding the new one.

Go ahead and change that to following.

operations = [
    migrations.RenameField(
        model_name='foo',
        old_name='orig_name',
        new_name='name')
]

Now run python manage.py migrate it'll rename the column in DB without losing data.


It is quite easy to fix. But you will have to modify the migration yourself.

Instead of dropping and adding the column, use db.rename_column. You can simply modify the migration created by schemamigration --auto