Creating and applying migrations

Now that we have a data model for our blog posts, we will need a database table for it. Django comes with a migration system that tracks the changes done to models and allows to propagate them into the database. The migrate command applies migrations for all applications listed in INSTALLED_APPS; it synchronizes the database with the current models and existing migrations.

First, you will need to create an initial migration for our Post model. In the root directory of your project, run the following command:

python manage.py makemigrations blog

You should get the following output:

Migrations for 'blog':
blog/migrations/0001_initial.py
- Create model Post

Django just created the 0001_initial.py file inside the migrations directory of the blog application. You can open that file to see how a migration appears. A migration specifies dependencies on other migrations and operations to perform in the database to synchronize it with model changes.

Let's take a look at the SQL code that Django will execute in the database to create the table for our model. The sqlmigrate command takes migration names and returns their SQL without executing it. Run the following command to inspect the SQL output of our first migration:

python manage.py sqlmigrate blog 0001

The output should look as follows:

BEGIN;
--
-- Create model Post
--
CREATE TABLE "blog_post" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "title" varchar(250) NOT NULL, "slug" varchar(250) NOT NULL, "body" text NOT NULL, "publish" datetime NOT NULL, "created" datetime NOT NULL, "updated" datetime NOT NULL, "status" varchar(10) NOT NULL, "author_id" integer NOT NULL REFERENCES "auth_user" ("id"));
CREATE INDEX "blog_post_slug_b95473f2" ON "blog_post" ("slug");
CREATE INDEX "blog_post_author_id_dd7a8485" ON "blog_post" ("author_id");
COMMIT;

The exact output depends on the database you are using. The preceding output is generated for SQLite. As you can see in the preceding output, Django generates the table names by combining the app name and the lowercase name of the model (blog_post), but you can also specify a custom database name for your model in the Meta class of the model using the db_table attribute. Django creates a primary key automatically for each model, but you can also override this by specifying primary_key=True in one of your model fields. The default primary key is an id column, which consists of an integer that is incremented automatically. This column corresponds to the id field that is automatically added to your models.

Let's sync our database with the new model. Run the following command to apply existing migrations:

python manage.py migrate

You will get an output that ends with the following line:

Applying blog.0001_initial... OK

We just applied migrations for the applications listed in INSTALLED_APPS, including our blog application. After applying migrations, the database reflects the current status of our models.

If you edit your models.py file in order to add, remove, or change fields of existing models, or if you add new models, you will have to create a new migration using the makemigrations command. The migration will allow Django to keep track of model changes. Then, you will have to apply it with the migrate command to keep the database in sync with your models.