Working with Django ORM migrations

Valerio Barbera

One of the key features of Django’s ORM is its migration system, which automates the process of database schema changes over time. In this tutorial, we will dive deep into understanding how Django ORM migrations work and how you can effectively use them in your projects.

As mentioned in previous articles, our machine learning APIs are built on top of Django, the most used framework to build REST applications in Python. And we use Django ORM to interact and maintain the SQL database.

This series of articles represents the knowledge we are building internally working with Django.

Overview of Django ORM Migrations

Django migrations allow developers to create, manage, and apply database schema changes over time, making it easier to evolve your database schema alongside your application. Migrations are written in Python and are stored as files in your Django project. They provide a version control-like system for database schemas.

Setting Up Migrations

To use ORM migrations in Django, you need to make sure that the django.contrib.migrations app is included in your project’s settings file (settings.py). This app is responsible for handling database migrations.

Creating Database Models

In Django, database models are defined as Python classes using Django’s django.db.models module. Each model class represents a database table, and the attributes of the class define the fields of the table. When creating or modifying models, Django’s migration system keeps track of the changes and generates corresponding migration files.

Here’s an example of a simple Django model representing a blog post:

from django.db import models
class Post(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)

Generating Migrations

Once you have defined your database models, you need to create migrations for them. Django provides a command-line utility called makemigrations that automatically creates migration files based on the changes you made to your models.

To generate migrations, run the following command in your terminal:

python manage.py makemigrations

Django will scan your models and generate a migration file (a Python file) for each database schema change.

Applying Migrations

After generating the migrations, you need to apply them to your database to make the corresponding schema changes. Django provides the migrate command to apply migrations.

To apply migrations, run the following command:

python manage.py migrate

Django will execute the migrations in the order they were created, updating your database schema accordingly.

Handling Database Schema Changes

As your project evolves, you might need to make changes to your existing models or add new models. Django’s migration system provides various operations to handle schema changes, such as adding fields, modifying fields, deleting fields, creating tables, and more.

Here are a few examples of common migration operations.

Adding a new field to an existing model

from django.db import migrations, models
class Migration(migrations.Migration):
    dependencies = [
        ('myapp', '0001_initial'),
    ]
    operations = [
        migrations.AddField(
            model_name='mymodel',
            name='new_field',
            field=models.CharField(max_length=50),
        ),
    ]

Modifying an existing field

from django.db import migrations, models
class Migration(migrations.Migration):
    dependencies = [
        ('myapp', '0002_previous_migration'),
    ]
    operations = [
        migrations.AlterField(
            model_name='mymodel',
            name='existing_field',
            field=models.IntegerField(),
        ),
    ]

Deleting a field

from django.db import migrations
class Migration(migrations.Migration):
    dependencies = [
        ('myapp', '0003_previous_migration'),
    ]
    operations = [
        migrations.RemoveField(
            model_name='mymodel',
            name='obsolete_field',
        ),
    ]

Advanced Migration Operations

Django ORM migrations also support more advanced operations, such as data migrations, running custom SQL, creating indexes, and more. These operations can be used to perform complex database schema changes.

For example, here’s a data migration that populates a newly added field with some initial values:

from django.db import migrations
def populate_new_field(apps, schema_editor):
    MyModel = apps.get_model('myapp', 'MyModel')
    for instance in MyModel.objects.all():
        instance.new_field = 'default value'
        instance.save()
class Migration(migrations.Migration):
    dependencies = [
        ('myapp', '0004_auto_20230101_1234'),
    ]
    operations = [
        migrations.RunPython(populate_new_field),
    ]

Rolling Back Migrations

Django provides a way to reverse previously applied migrations using the migrate command with the –fake or –fake-initial option. This allows you to roll back migrations in case of errors or when you need to revert to a previous state.

For example, to rollback the last applied migration, use the following command:

python manage.py migrate myapp 0003_previous_migration --fake

Migrations in Production

When deploying your Django application to production, it is crucial to have a solid migration strategy. It’s recommended to apply migrations as part of your deployment process to ensure your database schema is always up to date.

You can automate the migration process by running the migrate command during deployment or using tools like Django’s migrate management command in combination with deployment tools like Ansible, Fabric, or Docker.

New to Inspector? Try it for free now

Are you responsible for application development in your company? Consider trying my product Inspector to find out bugs and bottlenecks in your Django applucations automatically. Before your customers stumble onto the problem.

Inspector is usable by any IT leader who doesn’t need anything complicated. If you want effective automation, deep insights, and the ability to forward alerts and notifications into your preferred messaging environment try Inspector for free. Register your account.

Or learn more on the website: https://inspector.dev

Related Posts

Create a query for histogram charts with MySQL – Tutorial

To create a statistical query to build a histogram chart with MySQL, you can use the COUNT() function along with GROUP BY to count occurrences of values within a specified range or category created by the grouping constraint.  Especially for time series data there are a lot of use cases for histograms like monitoring the

Try the new Google Chat notification channel

Hi, I’m happy to announce that Google Chat is now available as a notification channel for your application. Now you can receive all important notifications of what happens in your application in your Google Chat environment in real time. Inspector Notification Channels allow you to create an automated and  informed workplace, helping your collaborators to

AI content creation to help you improve the Developer Experience

Co-founders are the first people in the trenches for any start-up, taking the idea and turning it into a sustainable business that can really make other people’s life better. In these early years of Inspector I have never told about my co-founders thanks to whom I was able to spend all my time building the