{"id":32404,"date":"2023-04-07T01:26:36","date_gmt":"2023-04-07T08:26:36","guid":{"rendered":"https:\/\/coderpad.io\/?p=32404"},"modified":"2023-06-05T13:36:03","modified_gmt":"2023-06-05T20:36:03","slug":"how-to-get-up-and-running-with-django-migrations-a-guide","status":"publish","type":"post","link":"https:\/\/coderpad.io\/blog\/development\/how-to-get-up-and-running-with-django-migrations-a-guide\/","title":{"rendered":"How To Get Up And Running With Django Migrations: A Guide"},"content":{"rendered":"\n<p>Django is a <a href=\"https:\/\/www.djangoproject.com\/\" target=\"_blank\" rel=\"noopener\">popular Python web framework<\/a> for building web applications. One of its key features is its support for migrations, which allows developers to manage changes to their database schema over time easily. In this guide, I&#8217;ll walk you through the process of getting started with Django migrations, including creating and applying them and resolving typical problems that may arise. Whether you&#8217;re new to Django or an experienced developer, this guide will help you understand and take full advantage of this powerful feature.&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>What are Django migrations?<\/strong><\/h2>\n\n\n\n<p>Django migrations are a way of handling the application of changes to a database schema.<\/p>\n\n\n\n<p>Among others, here are some of the many changes you might want to make to your database schema:&nbsp;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>create a new database table<\/li>\n\n\n\n<li>add new fields to database tables<\/li>\n\n\n\n<li>modify constraints in a database table<\/li>\n<\/ul>\n\n\n\n<p><a href=\"https:\/\/docs.djangoproject.com\/en\/4.1\/topics\/migrations\/\" target=\"_blank\" rel=\"noopener\">Django\u2019s documentation<\/a> explains Django migrations as analogous to a version control system (or VCS for short). It explains that you can use <code>makemigrations<\/code>&nbsp;to create individual migration files, similar to <code>commits<\/code>. Migration files contain changes you\u2019ll make to your models. The <code>migrate<\/code> command implements those changes to your database.&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Purpose of migration<\/strong><\/h2>\n\n\n\n<p>As you probably know, Django offers a way to manage databases without having to <a href=\"https:\/\/coderpad.io\/blog\/development\/sql-functions-and-techniques-every-data-person-should-know\/\">write raw Structured Query Language (SQL)<\/a>. The object-relational mapper (ORM) Django provides eliminates writing SQL statements, so you can interact with the database using Python code. In other words, you can create a database table by creating a simple model <a href=\"https:\/\/coderpad.io\/blog\/development\/classes-object-oriented-programming-python\/\">class<\/a>.&nbsp;<\/p>\n\n\n\n<p>However, because SQL is the standard language for interacting with databases (i.e., storing, manipulating, and retrieving data), Django still uses SQL to manage the database. But Django turns the ORM codes and models them into valid SQL statements to simplify things for you. So, how does this model class in Python translate into or become a database schema change? Django migrations takes care of that.&nbsp;<\/p>\n\n\n\n<p>Now that you know why and when to perform Django migrations, let&#8217;s discuss how.&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>How to run Django migrations<\/strong><\/h2>\n\n\n\n<p>There are four main commands for handling migrations and database schemas in Django.&nbsp;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>showmigrations<\/code>: shows the list of all migrations in a project and their current status (i.e., changes applied or not).<\/li>\n\n\n\n<li><code>sqlmigrate<\/code>:&nbsp;displays the SQL statements that will be executed for a specific migration.<\/li>\n\n\n\n<li><code>migrate<\/code>:&nbsp;implements the changes contained in migration files and updates the database schemas accordingly.<\/li>\n\n\n\n<li><code>makemigrations<\/code>:&nbsp;makes new migration files according to the modifications made to the models.<\/li>\n<\/ul>\n\n\n\n<p>If you paid attention to the above commands, you noticed that two unique keywords persist: <code>migrate<\/code>&nbsp;and <code>migrations<\/code>. That\u2019s because migrations require two phases (or steps).&nbsp;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>In the first step, you make migrations (i.e., create migration files), as you can infer from the command&#8217;s name (<code>makemigrations<\/code>).<\/li>\n\n\n\n<li>In the second step, you apply the migrations (<code>migrate<\/code>).<\/li>\n<\/ul>\n\n\n\n<p>In order to illustrate and demonstrate the Django migration workflow, let&#8217;s work with a Django project.&nbsp;<\/p>\n\n\n\n<p>Create a Django project and a new app called <code>blog<\/code>&nbsp;by running this command:&nbsp;<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css shcb-wrap-lines\"><span class=\"hljs-selector-tag\">python<\/span> <span class=\"hljs-selector-tag\">manage<\/span><span class=\"hljs-selector-class\">.py<\/span> <span class=\"hljs-selector-tag\">startapp<\/span> <span class=\"hljs-selector-tag\">blog<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p><strong>Step 1:<\/strong> Go to the <code>blog<\/code> app directory, and enter the following to create the <code>Blog<\/code> model in the <code>models.py<\/code>&nbsp;file.&nbsp;<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python shcb-wrap-lines\"><span class=\"hljs-keyword\">from<\/span> django.db <span class=\"hljs-keyword\">import<\/span> models\n\n<span class=\"hljs-keyword\">from<\/span> django.contrib.auth <span class=\"hljs-keyword\">import<\/span> get_user_model\n\nUser = get_user_model()\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Blog<\/span><span class=\"hljs-params\">(models.Model)<\/span>:<\/span>\n\n<span class=\"hljs-string\">\"\"\" Blog Model that represents Blog Table \"\"\"<\/span>\n\n    title = models.CharField(max_length=<span class=\"hljs-number\">100<\/span>, unique=<span class=\"hljs-literal\">True<\/span>)\n\n    slug = models.SlugField(max_length=<span class=\"hljs-number\">50<\/span>, blank=<span class=\"hljs-literal\">True<\/span>)\n\n    author = models.ForeignKey(User, on_delete=models.CASCADE)\n\n    description = models.CharField(max_length=<span class=\"hljs-number\">1000<\/span>)\n\n    date_created = models.DateTimeField(auto_now_add=<span class=\"hljs-literal\">True<\/span>)\n\n    last_modified = models.DateTimeField(auto_now=<span class=\"hljs-literal\">True<\/span>)\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__str__<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\n\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-string\">\"self.title&#91;:20]\"<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p><strong>Step 2:<\/strong> Go to the command line interface (CLI for short), and in the root directory of the Django project folder, run this command.&nbsp;<\/p>\n\n\n\n<p><em>Note<\/em><strong>:<\/strong> Ensure that the <code>manage.py<\/code> file is present in your current working directory in order to avoid getting the <code><strong>No such file or<\/strong> <strong>directory<\/strong><\/code> error.&nbsp;<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs shcb-wrap-lines\">$ python manage.py makemigrations<\/code><\/span><\/pre>\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2023\/03\/img_6421ac0253492.png\" alt=\"\"\/><\/figure>\n\n\n\n<p>The image above shows the output of running the above command.&nbsp;<\/p>\n\n\n\n<p><strong>Common Problem 1:<\/strong> Not adding the Django App in <code>installed_apps<\/code> in the Django project&#8217;s settings.&nbsp;<\/p>\n\n\n\n<p>The part labeled 1 in the image above is the output you&#8217;ll get when you run this command without adding the <code>blog<\/code> app as part of the installed apps. The output is &#8220;No changes detected&#8221; as no database fields or tables have been added or modified as far as Django is concerned.&nbsp;<\/p>\n\n\n\n<p><strong>Fix for Common Problem 1:<\/strong>&nbsp;<\/p>\n\n\n\n<p>Remember to add the newly created app <code>blog<\/code>&nbsp;to the <code>installed_apps<\/code>&nbsp;<a href=\"https:\/\/coderpad.io\/blog\/development\/python-list-comprehension-guide\/\">list<\/a> in the Django project&#8217;s settings.&nbsp;<\/p>\n\n\n\n<p>Also, in the image, the part labeled <strong>2<\/strong> is the output you get when you run this command after adding the <code>blog<\/code> app as part of the installed apps. In the output in the image above, you can see the name of the migration file created and its path.&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Overview of Migration File<\/strong><\/h2>\n\n\n\n<p>Now that you know how to create a Django migration file, we\u2019ll briefly explain the Django migration file.&nbsp;<\/p>\n\n\n\n<p><a href=\"https:\/\/docs.djangoproject.com\/en\/4.1\/topics\/migrations\/#migration-files\" target=\"_blank\" rel=\"noopener\">The migration file<\/a> contains a set of statements that instruct Django on the necessary database schema changes. Django uses these instructions to generate SQL statements that make the schema changes. These migration files are usually stored in the app folder, which sits in the migrations folder. Moreover, the migration file is a Python file containing two important things.&nbsp;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Operations<\/li>\n\n\n\n<li>Dependencies<\/li>\n<\/ul>\n\n\n\n<p>You need to pay attention to your Python code, but you also need to familiarize yourself with the migration file. To this end, you can open the migration file to see the list of operations and identify the create blog model operation in the list, as shown in the CLI output.&nbsp;&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2023\/03\/img_6421ac03cfa20.png\" alt=\"Initial migration file\n\" width=\"838\" height=\"420\"\/><\/figure>\n\n\n\n<blockquote class=\"wp-block-quote\">\n<p>\u2139\ufe0f You can <a href=\"https:\/\/docs.djangoproject.com\/en\/4.1\/ref\/settings\/#std-setting-MIGRATION_MODULES\" target=\"_blank\" rel=\"noopener\">override the name of the package<\/a> that contains the migrations on a per-app basis.&nbsp;<\/p>\n<\/blockquote>\n\n\n\n<p>Remember that the database table corresponding to our model has not actually been created yet. As a matter of fact, you can check the <code>db.sqlite3<\/code> file to confirm this. This makes sense because you haven&#8217;t yet run the <code>migrate<\/code>&nbsp;command.&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2023\/03\/img_6421ac049a062.png\" alt=\"\"\/><\/figure>\n\n\n\n<p>Run the command below actually to apply the schema changes to the database (i.e., to create a new blog database table). In other words, perform the operations defined in the migrations files.&nbsp;<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs shcb-wrap-lines\">$ python manage.py migrate<\/code><\/span><\/pre>\n\n\n<p>You\u2019ll see output similar to the output in the image below.&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2023\/03\/img_6421ac055c0f6.png\" alt=\"\"\/><\/figure>\n\n\n\n<p>Breakdown of the migrate command output:&nbsp;<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>The apps you\u2019re applying the migrations to<\/li>\n\n\n\n<li>The migrations files list<\/li>\n<\/ol>\n\n\n\n<p>The migrations files not highlighted are those that come default with Django.&nbsp;<\/p>\n\n\n\n<p>If you check the database at this point, you&#8217;ll see that several tables have been created, as shown in the image below.&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2023\/03\/img_6421ac061b189.png\" alt=\"\"\/><\/figure>\n\n\n\n<p>The tables not highlighted are those created by Django by default.&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Adding Dummy Data for Testing<\/strong><\/h2>\n\n\n\n<p>Now that you\u2019ve created your database tables, let&#8217;s add some data for testing.&nbsp;<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>To simplify adding data, you can use the Django admin dashboard. But first, you need to register the blog model in the <code>blog\/admin.py<\/code> file:<\/li>\n<\/ol>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python shcb-wrap-lines\"><span class=\"hljs-keyword\">from<\/span> django.contrib <span class=\"hljs-keyword\">import<\/span> admin\n\n<span class=\"hljs-keyword\">from<\/span> .models <span class=\"hljs-keyword\">import<\/span> Blog\n\n<span class=\"hljs-comment\"># Register your models here.<\/span>\n\n<span class=\"hljs-meta\">@admin.register(Blog)<\/span>\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">BlogAdmin<\/span><span class=\"hljs-params\">(admin.ModelAdmin)<\/span>:<\/span>\n\n\u00a0\u00a0\u00a0\u00a0list_display = &#91;<span class=\"hljs-string\">\"id\"<\/span>, <span class=\"hljs-string\">\"title\"<\/span>, <span class=\"hljs-string\">\"author\"<\/span>, <span class=\"hljs-string\">\"date_created\"<\/span>]<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<ol class=\"wp-block-list\" start=\"2\">\n<li>&nbsp;Next, run this command to create a superuser that can access the admin dashboard:<\/li>\n<\/ol>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs shcb-wrap-lines\">$ python manage.py createsuperuser<\/code><\/span><\/pre>\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2023\/03\/img_6421ac06eeb6b.png\" alt=\"\"\/><\/figure>\n\n\n\n<ol class=\"wp-block-list\" start=\"3\">\n<li>Start the development server:<\/li>\n<\/ol>\n\n\n\n<p>python manage.py runserver<\/p>\n\n\n\n<ol class=\"wp-block-list\" start=\"4\">\n<li>Navigate to http:\/\/127.0.0.1:8000\/admin, then log in.<\/li>\n\n\n\n<li>Click on the <strong>Add<\/strong> button under <strong>Blogs<\/strong>\u00a0and add some dummy data for testing.<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2023\/03\/img_6421ac076cdce.png\" alt=\"\"\/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong><\/strong><strong>Making Changes to Existing Models<\/strong><\/h2>\n\n\n\n<p>Software requirements change from time to time, and some changes necessitate adding additional fields or changing existing fields. As a result, you&#8217;ll need to make changes to your models. Let&#8217;s see how you can propagate those changes to your database schema.&nbsp;<\/p>\n\n\n\n<p>Imagine that the new change we need to make requires you to store the number of views for each blog post.&nbsp;<\/p>\n\n\n\n<p>To store the number, you need to add a field to the existing <code>Blog<\/code>\u00a0model.\u00a0<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python shcb-wrap-lines\">...\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Blog<\/span><span class=\"hljs-params\">(models.Model)<\/span>:<\/span>\n\n<span class=\"hljs-string\">\"\"\" Blog Model that represents Blog Table \"\"\"<\/span>\n\n...\n\n\u00a0\u00a0\u00a0\u00a0no_of_views = models.PositiveIntegerField() <span class=\"hljs-comment\"># new field<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p><strong>Django Migrations Default Value<\/strong><\/p>\n\n\n\n<p>Of course, you need to perform the two-step migration workflow before the new field can appear in the database.&nbsp;<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Run the <code>makemigration<\/code>\u00a0command.<\/li>\n<\/ol>\n\n\n\n<p>The image above shows the output of running the <code>makemigrations<\/code>\u00a0command.\u00a0<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2023\/03\/img_6421ac07e6191.png\" alt=\"\"\/><\/figure>\n\n\n\n<p>The message tells you to specify a default value for the newly added field in the existing rows of the database.&nbsp;<\/p>\n\n\n\n<p>You have two options:&nbsp;<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>You can provide a one-off default for all existing rows.<\/li>\n\n\n\n<li>You can abort and add a default value into the field as an argument.<\/li>\n<\/ol>\n\n\n\n<p>For this example, let\u2019s provide a one-off default value by entering <strong>1<\/strong> as the chosen option and then specifying <strong>0<\/strong> as the one-off default value.&nbsp;<\/p>\n\n\n\n<blockquote class=\"wp-block-quote\">\n<p>\u2139\ufe0f If you check the migration file created earlier, you&#8217;ll see the <code>AddFeld<\/code>\u00a0operation and the default value 0 specified.\u00a0<\/p>\n<\/blockquote>\n\n\n\n<p>Before applying the changes to the database schema, you can inspect the SQL statements for the migration by running the <code>sqlmigrate<\/code>\u00a0command.\u00a0<\/p>\n\n\n\n<p><em>Note<\/em><strong>:<\/strong> Unlike the two migrations commands you&#8217;ve used so far, <code>sqlmigrate<\/code> requires two arguments: <code>app_label<\/code> and <code>migration_name<\/code>.\u00a0<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs shcb-wrap-lines\">$ python manage.py sqlmigrate blog 0002_blog_no_of_views<\/code><\/span><\/pre>\n\n\n<p>The output should be similar to the one in the image below.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2023\/03\/img_6421ac0862e15.png\" alt=\"\"\/><\/figure>\n\n\n\n<ol class=\"wp-block-list\" start=\"2\">\n<li>Run the <code>migrate<\/code> command. Afterward, you can view the new fields added and the default value specified for the existing data in the database.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Reversing Django Migration<\/strong><\/h2>\n\n\n\n<p>From the previous section, you learned that Django keeps track of changes made to the database by storing a migration file. As a result, you can revert to the previous database schema. Think of this as resetting your codebase to a previous commit in case of a glitch or other issue.&nbsp;<\/p>\n\n\n\n<p>Now, let&#8217;s say you decided you no longer want to store the number of times a blog was viewed. In this case, you need to remove it, but you must remember that you added the <code>no_of_views<\/code> field separately after the model had already been created. As a result, all you need to do is to roll back to your initial migration, when the model was created (i.e., the first migration within the <code>blog<\/code>\u00a0app). To do that, run this command:\u00a0<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs shcb-wrap-lines\">$ python manage.py migrate blog 0001_initial<\/code><\/span><\/pre>\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2023\/03\/img_6421ac08e5b43.png\" alt=\"\"\/><\/figure>\n\n\n\n<p>If you check your database table, you&#8217;ll see that the no_of_views column was dropped even though:&nbsp;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The migration file for adding the <code>no_of_views<\/code> field still exists in the migrations folder, and<\/li>\n\n\n\n<li>The definition of the <code>no_of_views<\/code> field still exists as part of the blog model attributes in <code>models.py<\/code>.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">What\u2019s the implication?\u00a0<\/h3>\n\n\n\n<p>Remember the <code>showmigrations<\/code> command from the previous section? Run it here.\u00a0<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2023\/03\/img_6421ac095a1ec.png\" alt=\"\"\/><\/figure>\n\n\n\n<p>As the image above shows, only <code>0002_blog_no_of_views<\/code> looks odd (i.e., it has no times (X) symbol).\u00a0<\/p>\n\n\n\n<blockquote class=\"wp-block-quote\">\n<p>\u2139\ufe0f The times (X) symbol indicates the migration files were applied to the database schema.\u00a0<\/p>\n<\/blockquote>\n\n\n\n<p><strong>Common Problem 2: <\/strong>Reversing migration without deleting the migration file.&nbsp;<\/p>\n\n\n\n<p>If you try to run the <code>migrate<\/code> command, Django applies the pending migration file (i.e., <code>0002_blog_no_of_views<\/code>), even though you don&#8217;t want it to.\u00a0<\/p>\n\n\n\n<p><strong>Fix for Common Problem 2<\/strong>&nbsp;<\/p>\n\n\n\n<p>You need to delete the migration file that contains changes you don&#8217;t want. See the next section for how to do that!&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>How to Delete a Django Migration?<\/strong><\/h2>\n\n\n\n<p>Deleting a migration requires two steps:&nbsp;<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Delete the migration file associated with the change you no longer need.<\/li>\n<\/ol>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs shcb-wrap-lines\">$ rm blog\/migrations\/0002_blog_no_of_views.py<\/code><\/span><\/pre>\n\n\n<ol class=\"wp-block-list\" start=\"2\">\n<li>Change your model to match the latest migration file you created or whichever you want to keep.<\/li>\n<\/ol>\n\n\n\n<p><strong>Common Problem 3: <\/strong><code>Django won't apply migration<\/code>  error.\u00a0<\/p>\n\n\n\n<p>If you try to run a migrate command without performing second step, you&#8217;ll get the error depicted in the image below.&nbsp;<\/p>\n\n\n\n<p>This happens because the <code>migrate<\/code> command scans and then compares the models to the versions currently contained in the migration file. If it detects changes that don&#8217;t have an associated migration file, the database won&#8217;t know how to handle the changes made to the model and you\u2019ll get an error. This error occurs because the changes made to the models aren&#8217;t reflected in the migration files and hence, the database can\u2019t keep track of the changes and apply them.\u00a0<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/d2h1bfu6zrdxog.cloudfront.net\/wp-content\/uploads\/2023\/03\/img_6421ac09cc2ec.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><strong>Fix for Common Problem 3:<\/strong>&nbsp;<\/p>\n\n\n\n<p>Perform second step mentioned above by removing the entire <code>no_of_views<\/code> attribute in the <code>Blog<\/code> class.\u00a0<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>How to Make Fake Migrations in Django<\/strong><\/h2>\n\n\n\n<p>As with all commands generally, the Django migration commands take extra arguments. Extra arguments allow you to add customizations and configurations to the migration. One of these extra arguments is <em>fake<\/em>, which allows you to do fake migrations. The <code>--fake<\/code> argument in Django migrations allows you to mark one or multiple migrations as already applied without actually running their SQL statements. This can be useful in cases where you want to see what changes a migration would make to your database, but you don&#8217;t want any actual changes to the database schema.\u00a0<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Django Migration Best Practices<\/strong><\/h2>\n\n\n\n<p>Best practices you should adhere to when working with Django migrations include the following.&nbsp;<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Run migration files consistently across all environments.<\/strong> Migration files are part of the codebase. As a result, you&#8217;d commit and distribute them as part of the codebase. It is essential to ensure you run the migration files consistently across all environments, such as development, staging, and production to avoid inconsistencies in the database schema.<\/li>\n\n\n\n<li><strong>Test your migrations thoroughly.<\/strong> Make sure to test your migrations on a test database before deploying them to production. This ensures that there are no issues with the migration that could cause data loss or other problems.<\/li>\n\n\n\n<li><strong>Use the &#8211;database option when applying migrations.<\/strong> This allows you to apply migrations to specific databases, which can be useful when working with multiple databases in a single project.<\/li>\n\n\n\n<li><strong>Never edit your migration files manually.<\/strong> Always use the `<strong>makemigrations<\/strong>`&nbsp;command to create new migrations.<\/li>\n\n\n\n<li><strong>Be mindful of the order of migrations.<\/strong> Apply migrations in the order of their dependence on each other.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Conclusion<\/strong><\/h2>\n\n\n\n<p>Migrations are an indispensable part of Django. By following the steps outlined in this guide, you can easily set up and use migrations in your Django projects. Additionally, always strive to follow best practices.&nbsp;<\/p>\n\n\n\n<p><em>This post was written by Boluwatife Fayemi. <\/em><a href=\"https:\/\/bovage.hashnode.dev\" target=\"_blank\" rel=\"noopener\"><em>Boluwatife<\/em><\/a><em> is a Full Stack Web Developer, proficient in Javascript, Python, and their frameworks. His curiosity makes him explore and gain knowledge about a variety of topics. Boluwatife is passionate about teaching and writing, and this makes writing technical articles an enjoyable process for him.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Django migrations are a way of handling the application of changes to a database schema. By following the steps outlined in this guide, you can easily set up and use migrations in your Django projects.<\/p>\n","protected":false},"author":1,"featured_media":32999,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[9],"tags":[],"persona":[29],"blog-programming-language":[37],"keyword-cluster":[],"class_list":["post-32404","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development"],"acf":[],"_links":{"self":[{"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/posts\/32404","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/comments?post=32404"}],"version-history":[{"count":20,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/posts\/32404\/revisions"}],"predecessor-version":[{"id":33001,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/posts\/32404\/revisions\/33001"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/media\/32999"}],"wp:attachment":[{"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/media?parent=32404"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/categories?post=32404"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/tags?post=32404"},{"taxonomy":"persona","embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/persona?post=32404"},{"taxonomy":"blog-programming-language","embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/blog-programming-language?post=32404"},{"taxonomy":"keyword-cluster","embeddable":true,"href":"https:\/\/coderpad.io\/wp-json\/wp\/v2\/keyword-cluster?post=32404"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}