paint-brush
A Beginner's Guide to Deploying Django Model Changes to Productionby@shv
1,990 reads
1,990 reads

A Beginner's Guide to Deploying Django Model Changes to Production

by Aleksei SharypovJanuary 16th, 2023
Read on Terminal Reader
Read this story w/o Javascript

Too Long; Didn't Read

Production is a software and hardware complex that is available to end users. It includes servers, virtual machines, and containers with stable software installed. There are many requirements for production. However, in this article, we will focus on efficiency and continuity. The general approaches to applying this to production are shown in these very examples.
featured image - A Beginner's Guide to Deploying Django Model Changes to Production
Aleksei Sharypov HackerNoon profile picture

You can find many articles on the internet on how to deploy a Django project to production for the first time. But, what should you do when your project is already on production, and during deployments, you need to ensure the consistency of related systems and, at the same time, the continuity of your product?

What is Production?

Production is a software and hardware complex that is available to end users. It includes servers, virtual machines, and containers with stable software installed.

There are many requirements for production. However, in this article, we will focus on efficiency and continuity.

Efficiency is a guarantee that the product will do what it is supposed to do.

Continuity is a guarantee of efficient work while using this product.

That is, if a login attempt always returns an error, this is lack of efficiency. But, if a user rarely receives such an error, then this is a violation of continuity.

Initial Data

Several containers, virtual machines, or servers are used on production depending on the architecture.

I do not consider the situation when only one process is working on one server on production since it is similar to the usual development environment.

Production Scheme

General production scheme


In general, you most often encounter the scheme with several containers. They are accessed through a balancer. There may be more than one balancer. From containers, one database is accessed, but there may be several databases including sharding and replicas. They can also access brokers like Kafka and other services. Other services can also somehow exchange information with backends.

Simultaneous Changes in Code and Database

For example, let us consider only changes to code and a database.

The changes that can be made in code so that this affects a database and vice versa:

  1. Add/remove a table.
  2. Add/remove a column.
  3. Rename a column or table.
  4. Change the column type.
  5. Change the attributes (index) of the column (NULL, unique, default).


You can also add triggers and functions, change the scheme, and many more. However, the general approaches to applying this to production are shown in these very examples.

Detailed Example

If you need to add a model (table) to an application locally in the development environment, then you should do the following:


  1. Add a class to a Django model.
  2. Call the command: python manage.py makemigrations.
  3. Then: python manage.py migrate.
  4. And only after that, restart the application.


But on production, there are many instances of your application, git, and a separate process for running migrations.


You do not often have direct access to Prod. And this is good. For example, the flow might look like this.

Code replacement general sequence


In such a scheme, migrations are run first. Then, one by one, pods are restarted.


In such an architecture, there may always be a situation when migrations have been performed, but the code on production has not changed.

Changing DB before code


Then the pods are being replaced. Some instances have new code, some have the old one.


Moreover, if you perform migrations when pod replacement is completed, a different situation will take place: the code on the server is updated, but the database is not.

Both situations


Both situations imply some period of time when the database and the code are inconsistent.


Fortunately, Django does not check for consistency. However, the absence of the necessary elements results in exceptions.

They are:

  1. The presence of a class in the model in the code, but the absence of it in the database
  2. The presence of a field in the class in the code, but the absence of it in the database
  3. Different names of tables and columns in the code and database
  4. Different types of data in the code and table
  5. Default values, NULL, and other differences, if it comes to using them
  6. Other differences that the database does not expect when accessed from the code

Solutions

Migration needs to be performed before changing code when this implies:


  1. Adding a table
  2. Adding a column
  3. Adding the ability to insert NULL into the field


Migration needs to be performed after changing code when this implies:


  1. Removing a table
  2. Removing a column
  3. Removing the ability to insert NULL into the field


Renaming is performed in several steps:


  1. Creating a new field or table
  2. Adding synchronization of a new and old field or table
  3. Copying historical data if needed
  4. Starting to use a new field or table
  5. Removing an old field or table along with synchronization


All this seems complicated. But look at the schemes given above. On multi-pod production, during deployment, it always happens that part of the code works with the old database scheme while other part works with the new one. This may result in exceptions.


Thus, the basic algorithms for dealing with Django models do not work when it comes to production. Changes need to be deployed in several steps depending on the code architecture and CI / CD flow used in a particular case.


However, when making changes, you can always be guided by what the code expects when sending requests to the database. Beside standard cases, there may be various exceptions and obstacles that require ingenuity to find a way around.


In the upcoming articles, I will describe in detail some of the cases mentioned here.