Migrating database schema changes is crucial when developing Django applications over time. Often, you may realize you need to rename a model field to something more appropriate. However, renaming fields isn’t as straightforward as it may initially seem. In this post, we’ll explore how to properly rename fields with South.
An Introduction to South
South is a third-party library that enables Django projects to have schema and data migrations. In other words, South tracks changes you make to your models and database schema and handles transitioning the database to the new structure safely and incrementally.
Without South, renaming fields would require dropping the old field and adding a new one. This would result in data loss, which is unacceptable. South gives us the capability to migrate databases more robustly.
The Perils of Manually Renaming Fields
Before learning the right way with South, let’s understand what goes wrong with naively renaming fields.
For example, let’s say we have a User
model with a first_name
field and want to rename it to first
. If we just open models.py
and rename it there, Django will still look for the old first_name
field name in the database when trying to interact with user data.
Therefore, we’ll get errors claiming the field doesn’t exist even though first_name
still resides in the database. Furthermore, any existing data would appear as null or lost without taking steps to migrate it to the new field name properly.
Using South Data Migrations
The key to renaming fields withSouth is using data migrations. Data migrations give us a programmatic way to manipulate the underlying database to transition it safely to our new model definition.
Here are the steps to rename a field with South:
- Install South if you haven’t already
- Make your model changes in
models.py
(e.g. rename the field) - Create a new empty migration file
./manage.py schemamigration appname --empty rename_first_name
- Edit the created migration file to contain a
forwards
andbackwards
data migration - Run
./manage.py migrate appname
to apply the migration
Taking our User
example above, our data migration would look like this:
def forwards(self, orm):
# Rename old fields
db.rename_column('app_user', 'first_name', 'first')
def backwards(self, orm):
# Rename new field back to old
db.rename_column('app_user', 'first', 'first_name')
We simply use South’s orm
API and some handy Django database functions to transition the columns. The forwards
function handles changing the schema for the migration, while backwards
gets called if we ever need to reverse the migration.
The Advantages of Data Migrations
As we can see, data migrations provide a straightforward way to reliably transition field names, while preserving our data safely.
Some key advantages include:
- Renaming columns without losing data
- Step-by-step incremental database migrations
- Schema changes are tracked in source control
- Changes can be reversed if needed
Overall, South data migrations bring needed control and safety to the otherwise messy process of renaming model fields in Django.
Conclusion
I hope this post gave you a good overview of how to properly rename model fields with South data migrations in Django. Migrating schema changes to existing production data is nontrivial, but South gives us the tools we need.
The key takeaways are:
- Simply renaming fields in
models.py
will break your data access - South data migrations allow safe, incremental database transitions
- The
forwards
/backwards
migration functions rename columns while preserving data
As you can see, South brings needed rigor to Django database migrations. I highly recommend using it over attempting manual schema changes once your application is beyond basic prototyping stages.