{"title":"How to create database migrations","version":"5.0","locale":"en","docname":"howto/writing-migrations","url":"/en/5.0/howto/writing-migrations/","canonical":"https://djangodocs.dev/en/5.0/howto/writing-migrations/","summary":"This document explains how to structure and write database migrations for different scenarios you might encounter. For introductory material on migrations, see the…","html":"<h1>How to create database migrations<a class=\"heading-anchor\" href=\"#how-to-create-database-migrations\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>This document explains how to structure and write database migrations for\ndifferent scenarios you might encounter. For introductory material on\nmigrations, see <a class=\"reference internal\" href=\"/en/5.0/topics/migrations/\"><span class=\"doc\">the topic guide</span></a>.</p>\n<section id=\"data-migrations-and-multiple-databases\">\n<span id=\"id1\"></span><h2>Data migrations and multiple databases<a class=\"heading-anchor\" href=\"#data-migrations-and-multiple-databases\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>When using multiple databases, you may need to figure out whether or not to\nrun a migration against a particular database. For example, you may want to\n<strong>only</strong> run a migration on a particular database.</p>\n<p>In order to do that you can check the database connection’s alias inside a\n<code class=\"docutils literal notranslate\">RunPython</code> operation by looking at the <code class=\"docutils literal notranslate\">schema_editor.connection.alias</code>\nattribute:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.db</span> <span class=\"kn\">import</span> migrations\n\n\n<span class=\"k\">def</span> <span class=\"nf\">forwards</span><span class=\"p\">(</span>apps<span class=\"p\">,</span> schema_editor<span class=\"p\">):</span>\n    <span class=\"k\">if</span> schema_editor<span class=\"o\">.</span>connection<span class=\"o\">.</span>alias <span class=\"o\">!=</span> <span class=\"s2\">&quot;default&quot;</span><span class=\"p\">:</span>\n        <span class=\"k\">return</span>\n    <span class=\"c1\"># Your migration code goes here</span>\n\n\n<span class=\"k\">class</span> <span class=\"nc\">Migration</span><span class=\"p\">(</span>migrations<span class=\"o\">.</span>Migration<span class=\"p\">):</span>\n    dependencies <span class=\"o\">=</span> <span class=\"p\">[</span>\n        <span class=\"c1\"># Dependencies to other migrations</span>\n    <span class=\"p\">]</span>\n\n    operations <span class=\"o\">=</span> <span class=\"p\">[</span>\n        migrations<span class=\"o\">.</span>RunPython<span class=\"p\">(</span>forwards<span class=\"p\">),</span>\n    <span class=\"p\">]</span>\n</code></pre></div>\n<p>You can also provide hints that will be passed to the <a class=\"reference internal\" href=\"/en/5.0/topics/db/multi-db/#allow_migrate\" title=\"allow_migrate\"><code class=\"xref py py-meth docutils literal notranslate\">allow_migrate()</code></a>\nmethod of database routers as <code class=\"docutils literal notranslate\">**hints</code>:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\">myapp/dbrouters.py</code></figcaption>\n<div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python code\"><code><span class=\"k\">class</span> <span class=\"nc\">MyRouter</span><span class=\"p\">:</span>\n    <span class=\"k\">def</span> <span class=\"nf\">allow_migrate</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> db<span class=\"p\">,</span> app_label<span class=\"p\">,</span> model_name<span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"o\">**</span>hints<span class=\"p\">):</span>\n        <span class=\"k\">if</span> <span class=\"s2\">&quot;target_db&quot;</span> <span class=\"ow\">in</span> hints<span class=\"p\">:</span>\n            <span class=\"k\">return</span> db <span class=\"o\">==</span> hints<span class=\"p\">[</span><span class=\"s2\">&quot;target_db&quot;</span><span class=\"p\">]</span>\n        <span class=\"k\">return</span> <span class=\"kc\">True</span>\n</code></pre></figure>\n<p>Then, to leverage this in your migrations, do the following:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.db</span> <span class=\"kn\">import</span> migrations\n\n\n<span class=\"k\">def</span> <span class=\"nf\">forwards</span><span class=\"p\">(</span>apps<span class=\"p\">,</span> schema_editor<span class=\"p\">):</span>\n    <span class=\"c1\"># Your migration code goes here</span>\n    <span class=\"o\">...</span>\n\n\n<span class=\"k\">class</span> <span class=\"nc\">Migration</span><span class=\"p\">(</span>migrations<span class=\"o\">.</span>Migration<span class=\"p\">):</span>\n    dependencies <span class=\"o\">=</span> <span class=\"p\">[</span>\n        <span class=\"c1\"># Dependencies to other migrations</span>\n    <span class=\"p\">]</span>\n\n    operations <span class=\"o\">=</span> <span class=\"p\">[</span>\n        migrations<span class=\"o\">.</span>RunPython<span class=\"p\">(</span>forwards<span class=\"p\">,</span> hints<span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s2\">&quot;target_db&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;default&quot;</span><span class=\"p\">}),</span>\n    <span class=\"p\">]</span>\n</code></pre></div>\n<p>If your <code class=\"docutils literal notranslate\">RunPython</code> or <code class=\"docutils literal notranslate\">RunSQL</code> operation only affects one model, it’s good\npractice to pass <code class=\"docutils literal notranslate\">model_name</code> as a hint to make it as transparent as possible\nto the router. This is especially important for reusable and third-party apps.</p>\n</section>\n<section id=\"migrations-that-add-unique-fields\">\n<h2>Migrations that add unique fields<a class=\"heading-anchor\" href=\"#migrations-that-add-unique-fields\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Applying a “plain” migration that adds a unique non-nullable field to a table\nwith existing rows will raise an error because the value used to populate\nexisting rows is generated only once, thus breaking the unique constraint.</p>\n<p>Therefore, the following steps should be taken. In this example, we’ll add a\nnon-nullable <a class=\"reference internal\" href=\"/en/5.0/ref/models/fields/#django.db.models.UUIDField\" title=\"django.db.models.UUIDField\"><code class=\"xref py py-class docutils literal notranslate\">UUIDField</code></a> with a default value. Modify\nthe respective field according to your needs.</p>\n<ul>\n<li><p>Add the field on your model with <code class=\"docutils literal notranslate\">default=uuid.uuid4</code> and <code class=\"docutils literal notranslate\">unique=True</code>\narguments (choose an appropriate default for the type of the field you’re\nadding).</p></li>\n<li><p>Run the <a class=\"reference internal\" href=\"/en/5.0/ref/django-admin/#django-admin-makemigrations\"><code class=\"xref std std-djadmin docutils literal notranslate\">makemigrations</code></a> command. This should generate a migration\nwith an <code class=\"docutils literal notranslate\">AddField</code> operation.</p></li>\n<li><p>Generate two empty migration files for the same app by running\n<code class=\"docutils literal notranslate\">makemigrations myapp --empty</code> twice. We’ve renamed the migration files to\ngive them meaningful names in the examples below.</p></li>\n<li><p>Copy the <code class=\"docutils literal notranslate\">AddField</code> operation from the auto-generated migration (the first\nof the three new files) to the last migration, change <code class=\"docutils literal notranslate\">AddField</code> to\n<code class=\"docutils literal notranslate\">AlterField</code>, and add imports of <code class=\"docutils literal notranslate\">uuid</code> and <code class=\"docutils literal notranslate\">models</code>. For example:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\">0006_remove_uuid_null.py</code></figcaption>\n<div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python code\"><code><span class=\"c1\"># Generated by Django A.B on YYYY-MM-DD HH:MM</span>\n<span class=\"kn\">from</span> <span class=\"nn\">django.db</span> <span class=\"kn\">import</span> migrations<span class=\"p\">,</span> models\n<span class=\"kn\">import</span> <span class=\"nn\">uuid</span>\n\n\n<span class=\"k\">class</span> <span class=\"nc\">Migration</span><span class=\"p\">(</span>migrations<span class=\"o\">.</span>Migration<span class=\"p\">):</span>\n    dependencies <span class=\"o\">=</span> <span class=\"p\">[</span>\n        <span class=\"p\">(</span><span class=\"s2\">&quot;myapp&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;0005_populate_uuid_values&quot;</span><span class=\"p\">),</span>\n    <span class=\"p\">]</span>\n\n    operations <span class=\"o\">=</span> <span class=\"p\">[</span>\n        migrations<span class=\"o\">.</span>AlterField<span class=\"p\">(</span>\n            model_name<span class=\"o\">=</span><span class=\"s2\">&quot;mymodel&quot;</span><span class=\"p\">,</span>\n            name<span class=\"o\">=</span><span class=\"s2\">&quot;uuid&quot;</span><span class=\"p\">,</span>\n            field<span class=\"o\">=</span>models<span class=\"o\">.</span>UUIDField<span class=\"p\">(</span>default<span class=\"o\">=</span>uuid<span class=\"o\">.</span>uuid4<span class=\"p\">,</span> unique<span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">),</span>\n        <span class=\"p\">),</span>\n    <span class=\"p\">]</span>\n</code></pre></figure>\n</li>\n<li><p>Edit the first migration file. The generated migration class should look\nsimilar to this:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\">0004_add_uuid_field.py</code></figcaption>\n<div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python code\"><code><span class=\"k\">class</span> <span class=\"nc\">Migration</span><span class=\"p\">(</span>migrations<span class=\"o\">.</span>Migration<span class=\"p\">):</span>\n    dependencies <span class=\"o\">=</span> <span class=\"p\">[</span>\n        <span class=\"p\">(</span><span class=\"s2\">&quot;myapp&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;0003_auto_20150129_1705&quot;</span><span class=\"p\">),</span>\n    <span class=\"p\">]</span>\n\n    operations <span class=\"o\">=</span> <span class=\"p\">[</span>\n        migrations<span class=\"o\">.</span>AddField<span class=\"p\">(</span>\n            model_name<span class=\"o\">=</span><span class=\"s2\">&quot;mymodel&quot;</span><span class=\"p\">,</span>\n            name<span class=\"o\">=</span><span class=\"s2\">&quot;uuid&quot;</span><span class=\"p\">,</span>\n            field<span class=\"o\">=</span>models<span class=\"o\">.</span>UUIDField<span class=\"p\">(</span>default<span class=\"o\">=</span>uuid<span class=\"o\">.</span>uuid4<span class=\"p\">,</span> unique<span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">),</span>\n        <span class=\"p\">),</span>\n    <span class=\"p\">]</span>\n</code></pre></figure>\n<p>Change <code class=\"docutils literal notranslate\">unique=True</code> to <code class=\"docutils literal notranslate\">null=True</code> – this will create the intermediary\nnull field and defer creating the unique constraint until we’ve populated\nunique values on all the rows.</p>\n</li>\n<li><p>In the first empty migration file, add a\n<a class=\"reference internal\" href=\"/en/5.0/ref/migration-operations/#django.db.migrations.operations.RunPython\" title=\"django.db.migrations.operations.RunPython\"><code class=\"xref py py-class docutils literal notranslate\">RunPython</code></a> or\n<a class=\"reference internal\" href=\"/en/5.0/ref/migration-operations/#django.db.migrations.operations.RunSQL\" title=\"django.db.migrations.operations.RunSQL\"><code class=\"xref py py-class docutils literal notranslate\">RunSQL</code></a> operation to generate a\nunique value (UUID in the example) for each existing row. Also add an import\nof <code class=\"docutils literal notranslate\">uuid</code>. For example:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\">0005_populate_uuid_values.py</code></figcaption>\n<div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python code\"><code><span class=\"c1\"># Generated by Django A.B on YYYY-MM-DD HH:MM</span>\n<span class=\"kn\">from</span> <span class=\"nn\">django.db</span> <span class=\"kn\">import</span> migrations\n<span class=\"kn\">import</span> <span class=\"nn\">uuid</span>\n\n\n<span class=\"k\">def</span> <span class=\"nf\">gen_uuid</span><span class=\"p\">(</span>apps<span class=\"p\">,</span> schema_editor<span class=\"p\">):</span>\n    MyModel <span class=\"o\">=</span> apps<span class=\"o\">.</span>get_model<span class=\"p\">(</span><span class=\"s2\">&quot;myapp&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;MyModel&quot;</span><span class=\"p\">)</span>\n    <span class=\"k\">for</span> row <span class=\"ow\">in</span> MyModel<span class=\"o\">.</span>objects<span class=\"o\">.</span>all<span class=\"p\">():</span>\n        row<span class=\"o\">.</span>uuid <span class=\"o\">=</span> uuid<span class=\"o\">.</span>uuid4<span class=\"p\">()</span>\n        row<span class=\"o\">.</span>save<span class=\"p\">(</span>update_fields<span class=\"o\">=</span><span class=\"p\">[</span><span class=\"s2\">&quot;uuid&quot;</span><span class=\"p\">])</span>\n\n\n<span class=\"k\">class</span> <span class=\"nc\">Migration</span><span class=\"p\">(</span>migrations<span class=\"o\">.</span>Migration<span class=\"p\">):</span>\n    dependencies <span class=\"o\">=</span> <span class=\"p\">[</span>\n        <span class=\"p\">(</span><span class=\"s2\">&quot;myapp&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;0004_add_uuid_field&quot;</span><span class=\"p\">),</span>\n    <span class=\"p\">]</span>\n\n    operations <span class=\"o\">=</span> <span class=\"p\">[</span>\n        <span class=\"c1\"># omit reverse_code=... if you don&#39;t want the migration to be reversible.</span>\n        migrations<span class=\"o\">.</span>RunPython<span class=\"p\">(</span>gen_uuid<span class=\"p\">,</span> reverse_code<span class=\"o\">=</span>migrations<span class=\"o\">.</span>RunPython<span class=\"o\">.</span>noop<span class=\"p\">),</span>\n    <span class=\"p\">]</span>\n</code></pre></figure>\n</li>\n<li><p>Now you can apply the migrations as usual with the <a class=\"reference internal\" href=\"/en/5.0/ref/django-admin/#django-admin-migrate\"><code class=\"xref std std-djadmin docutils literal notranslate\">migrate</code></a> command.</p>\n<p>Note there is a race condition if you allow objects to be created while this\nmigration is running. Objects created after the <code class=\"docutils literal notranslate\">AddField</code> and before\n<code class=\"docutils literal notranslate\">RunPython</code> will have their original <code class=\"docutils literal notranslate\">uuid</code>’s overwritten.</p>\n</li>\n</ul>\n<section id=\"non-atomic-migrations\">\n<span id=\"id2\"></span><h3>Non-atomic migrations<a class=\"heading-anchor\" href=\"#non-atomic-migrations\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>On databases that support DDL transactions (SQLite and PostgreSQL), migrations\nwill run inside a transaction by default. For use cases such as performing data\nmigrations on large tables, you may want to prevent a migration from running in\na transaction by setting the <code class=\"docutils literal notranslate\">atomic</code> attribute to <code class=\"docutils literal notranslate\">False</code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.db</span> <span class=\"kn\">import</span> migrations\n\n\n<span class=\"k\">class</span> <span class=\"nc\">Migration</span><span class=\"p\">(</span>migrations<span class=\"o\">.</span>Migration<span class=\"p\">):</span>\n    atomic <span class=\"o\">=</span> <span class=\"kc\">False</span>\n</code></pre></div>\n<p>Within such a migration, all operations are run without a transaction. It’s\npossible to execute parts of the migration inside a transaction using\n<a class=\"reference internal\" href=\"/en/5.0/topics/db/transactions/#django.db.transaction.atomic\" title=\"django.db.transaction.atomic\"><code class=\"xref py py-func docutils literal notranslate\">atomic()</code></a> or by passing <code class=\"docutils literal notranslate\">atomic=True</code> to\n<code class=\"docutils literal notranslate\">RunPython</code>.</p>\n<p>Here’s an example of a non-atomic data migration that updates a large table in\nsmaller batches:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">import</span> <span class=\"nn\">uuid</span>\n\n<span class=\"kn\">from</span> <span class=\"nn\">django.db</span> <span class=\"kn\">import</span> migrations<span class=\"p\">,</span> transaction\n\n\n<span class=\"k\">def</span> <span class=\"nf\">gen_uuid</span><span class=\"p\">(</span>apps<span class=\"p\">,</span> schema_editor<span class=\"p\">):</span>\n    MyModel <span class=\"o\">=</span> apps<span class=\"o\">.</span>get_model<span class=\"p\">(</span><span class=\"s2\">&quot;myapp&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;MyModel&quot;</span><span class=\"p\">)</span>\n    <span class=\"k\">while</span> MyModel<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>uuid__isnull<span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span><span class=\"o\">.</span>exists<span class=\"p\">():</span>\n        <span class=\"k\">with</span> transaction<span class=\"o\">.</span>atomic<span class=\"p\">():</span>\n            <span class=\"k\">for</span> row <span class=\"ow\">in</span> MyModel<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>uuid__isnull<span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)[:</span><span class=\"mi\">1000</span><span class=\"p\">]:</span>\n                row<span class=\"o\">.</span>uuid <span class=\"o\">=</span> uuid<span class=\"o\">.</span>uuid4<span class=\"p\">()</span>\n                row<span class=\"o\">.</span>save<span class=\"p\">()</span>\n\n\n<span class=\"k\">class</span> <span class=\"nc\">Migration</span><span class=\"p\">(</span>migrations<span class=\"o\">.</span>Migration<span class=\"p\">):</span>\n    atomic <span class=\"o\">=</span> <span class=\"kc\">False</span>\n\n    operations <span class=\"o\">=</span> <span class=\"p\">[</span>\n        migrations<span class=\"o\">.</span>RunPython<span class=\"p\">(</span>gen_uuid<span class=\"p\">),</span>\n    <span class=\"p\">]</span>\n</code></pre></div>\n<p>The <code class=\"docutils literal notranslate\">atomic</code> attribute doesn’t have an effect on databases that don’t support\nDDL transactions (e.g. MySQL, Oracle). (MySQL’s <a class=\"reference external\" href=\"https://dev.mysql.com/doc/refman/en/atomic-ddl.html\">atomic DDL statement support</a> refers to individual\nstatements rather than multiple statements wrapped in a transaction that can be\nrolled back.)</p>\n</section>\n</section>\n<section id=\"controlling-the-order-of-migrations\">\n<h2>Controlling the order of migrations<a class=\"heading-anchor\" href=\"#controlling-the-order-of-migrations\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Django determines the order in which migrations should be applied not by the\nfilename of each migration, but by building a graph using two properties on the\n<code class=\"docutils literal notranslate\">Migration</code> class: <code class=\"docutils literal notranslate\">dependencies</code> and <code class=\"docutils literal notranslate\">run_before</code>.</p>\n<p>If you’ve used the <a class=\"reference internal\" href=\"/en/5.0/ref/django-admin/#django-admin-makemigrations\"><code class=\"xref std std-djadmin docutils literal notranslate\">makemigrations</code></a> command you’ve probably\nalready seen <code class=\"docutils literal notranslate\">dependencies</code> in action because auto-created\nmigrations have this defined as part of their creation process.</p>\n<p>The <code class=\"docutils literal notranslate\">dependencies</code> property is declared like this:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.db</span> <span class=\"kn\">import</span> migrations\n\n\n<span class=\"k\">class</span> <span class=\"nc\">Migration</span><span class=\"p\">(</span>migrations<span class=\"o\">.</span>Migration<span class=\"p\">):</span>\n    dependencies <span class=\"o\">=</span> <span class=\"p\">[</span>\n        <span class=\"p\">(</span><span class=\"s2\">&quot;myapp&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;0123_the_previous_migration&quot;</span><span class=\"p\">),</span>\n    <span class=\"p\">]</span>\n</code></pre></div>\n<p>Usually this will be enough, but from time to time you may need to\nensure that your migration runs <em>before</em> other migrations. This is\nuseful, for example, to make third-party apps’ migrations run <em>after</em>\nyour <a class=\"reference internal\" href=\"/en/5.0/ref/settings/#std-setting-AUTH_USER_MODEL\"><code class=\"xref std std-setting docutils literal notranslate\">AUTH_USER_MODEL</code></a> replacement.</p>\n<p>To achieve this, place all migrations that should depend on yours in\nthe <code class=\"docutils literal notranslate\">run_before</code> attribute on your <code class=\"docutils literal notranslate\">Migration</code> class:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span> <span class=\"nc\">Migration</span><span class=\"p\">(</span>migrations<span class=\"o\">.</span>Migration<span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n\n    run_before <span class=\"o\">=</span> <span class=\"p\">[</span>\n        <span class=\"p\">(</span><span class=\"s2\">&quot;third_party_app&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;0001_do_awesome&quot;</span><span class=\"p\">),</span>\n    <span class=\"p\">]</span>\n</code></pre></div>\n<p>Prefer using <code class=\"docutils literal notranslate\">dependencies</code> over <code class=\"docutils literal notranslate\">run_before</code> when possible. You should\nonly use <code class=\"docutils literal notranslate\">run_before</code> if it is undesirable or impractical to specify\n<code class=\"docutils literal notranslate\">dependencies</code> in the migration which you want to run after the one you are\nwriting.</p>\n</section>\n<section id=\"migrating-data-between-third-party-apps\">\n<h2>Migrating data between third-party apps<a class=\"heading-anchor\" href=\"#migrating-data-between-third-party-apps\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>You can use a data migration to move data from one third-party application to\nanother.</p>\n<p>If you plan to remove the old app later, you’ll need to set the <code class=\"docutils literal notranslate\">dependencies</code>\nproperty based on whether or not the old app is installed. Otherwise, you’ll\nhave missing dependencies once you uninstall the old app. Similarly, you’ll\nneed to catch <a class=\"reference external\" href=\"https://docs.python.org/3/library/exceptions.html#LookupError\" title=\"(in Python v3.14)\"><code class=\"xref py py-exc docutils literal notranslate\">LookupError</code></a> in the <code class=\"docutils literal notranslate\">apps.get_model()</code> call that\nretrieves models from the old app. This approach allows you to deploy your\nproject anywhere without first installing and then uninstalling the old app.</p>\n<p>Here’s a sample migration:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\">myapp/migrations/0124_move_old_app_to_new_app.py</code></figcaption>\n<div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.apps</span> <span class=\"kn\">import</span> apps <span class=\"k\">as</span> global_apps\n<span class=\"kn\">from</span> <span class=\"nn\">django.db</span> <span class=\"kn\">import</span> migrations\n\n\n<span class=\"k\">def</span> <span class=\"nf\">forwards</span><span class=\"p\">(</span>apps<span class=\"p\">,</span> schema_editor<span class=\"p\">):</span>\n    <span class=\"k\">try</span><span class=\"p\">:</span>\n        OldModel <span class=\"o\">=</span> apps<span class=\"o\">.</span>get_model<span class=\"p\">(</span><span class=\"s2\">&quot;old_app&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;OldModel&quot;</span><span class=\"p\">)</span>\n    <span class=\"k\">except</span> <span class=\"ne\">LookupError</span><span class=\"p\">:</span>\n        <span class=\"c1\"># The old app isn&#39;t installed.</span>\n        <span class=\"k\">return</span>\n\n    NewModel <span class=\"o\">=</span> apps<span class=\"o\">.</span>get_model<span class=\"p\">(</span><span class=\"s2\">&quot;new_app&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;NewModel&quot;</span><span class=\"p\">)</span>\n    NewModel<span class=\"o\">.</span>objects<span class=\"o\">.</span>bulk_create<span class=\"p\">(</span>\n        NewModel<span class=\"p\">(</span>new_attribute<span class=\"o\">=</span>old_object<span class=\"o\">.</span>old_attribute<span class=\"p\">)</span>\n        <span class=\"k\">for</span> old_object <span class=\"ow\">in</span> OldModel<span class=\"o\">.</span>objects<span class=\"o\">.</span>all<span class=\"p\">()</span>\n    <span class=\"p\">)</span>\n\n\n<span class=\"k\">class</span> <span class=\"nc\">Migration</span><span class=\"p\">(</span>migrations<span class=\"o\">.</span>Migration<span class=\"p\">):</span>\n    operations <span class=\"o\">=</span> <span class=\"p\">[</span>\n        migrations<span class=\"o\">.</span>RunPython<span class=\"p\">(</span>forwards<span class=\"p\">,</span> migrations<span class=\"o\">.</span>RunPython<span class=\"o\">.</span>noop<span class=\"p\">),</span>\n    <span class=\"p\">]</span>\n    dependencies <span class=\"o\">=</span> <span class=\"p\">[</span>\n        <span class=\"p\">(</span><span class=\"s2\">&quot;myapp&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;0123_the_previous_migration&quot;</span><span class=\"p\">),</span>\n        <span class=\"p\">(</span><span class=\"s2\">&quot;new_app&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;0001_initial&quot;</span><span class=\"p\">),</span>\n    <span class=\"p\">]</span>\n\n    <span class=\"k\">if</span> global_apps<span class=\"o\">.</span>is_installed<span class=\"p\">(</span><span class=\"s2\">&quot;old_app&quot;</span><span class=\"p\">):</span>\n        dependencies<span class=\"o\">.</span>append<span class=\"p\">((</span><span class=\"s2\">&quot;old_app&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;0001_initial&quot;</span><span class=\"p\">))</span>\n</code></pre></figure>\n<p>Also consider what you want to happen when the migration is unapplied. You\ncould either do nothing (as in the example above) or remove some or all of the\ndata from the new application. Adjust the second argument of the\n<a class=\"reference internal\" href=\"/en/5.0/ref/migration-operations/#django.db.migrations.operations.RunPython\" title=\"django.db.migrations.operations.RunPython\"><code class=\"xref py py-mod docutils literal notranslate\">RunPython</code></a> operation accordingly.</p>\n</section>\n<section id=\"changing-a-manytomanyfield-to-use-a-through-model\">\n<span id=\"id3\"></span><h2>Changing a <code class=\"docutils literal notranslate\">ManyToManyField</code> to use a <code class=\"docutils literal notranslate\">through</code> model<a class=\"heading-anchor\" href=\"#changing-a-manytomanyfield-to-use-a-through-model\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>If you change a <a class=\"reference internal\" href=\"/en/5.0/ref/models/fields/#django.db.models.ManyToManyField\" title=\"django.db.models.ManyToManyField\"><code class=\"xref py py-class docutils literal notranslate\">ManyToManyField</code></a> to use a <code class=\"docutils literal notranslate\">through</code>\nmodel, the default migration will delete the existing table and create a new\none, losing the existing relations. To avoid this, you can use\n<a class=\"reference internal\" href=\"/en/5.0/ref/migration-operations/#django.db.migrations.operations.SeparateDatabaseAndState\" title=\"django.db.migrations.operations.SeparateDatabaseAndState\"><code class=\"xref py py-class docutils literal notranslate\">SeparateDatabaseAndState</code></a> to rename the existing table to the new\ntable name while telling the migration autodetector that the new model has\nbeen created. You can check the existing table name through\n<a class=\"reference internal\" href=\"/en/5.0/ref/django-admin/#django-admin-sqlmigrate\"><code class=\"xref std std-djadmin docutils literal notranslate\">sqlmigrate</code></a> or <a class=\"reference internal\" href=\"/en/5.0/ref/django-admin/#django-admin-dbshell\"><code class=\"xref std std-djadmin docutils literal notranslate\">dbshell</code></a>. You can check the new table name\nwith the through model’s <code class=\"docutils literal notranslate\">_meta.db_table</code> property. Your new <code class=\"docutils literal notranslate\">through</code>\nmodel should use the same names for the <code class=\"docutils literal notranslate\">ForeignKey</code>s as Django did. Also if\nit needs any extra fields, they should be added in operations after\n<a class=\"reference internal\" href=\"/en/5.0/ref/migration-operations/#django.db.migrations.operations.SeparateDatabaseAndState\" title=\"django.db.migrations.operations.SeparateDatabaseAndState\"><code class=\"xref py py-class docutils literal notranslate\">SeparateDatabaseAndState</code></a>.</p>\n<p>For example, if we had a <code class=\"docutils literal notranslate\">Book</code> model with a <code class=\"docutils literal notranslate\">ManyToManyField</code> linking to\n<code class=\"docutils literal notranslate\">Author</code>, we could add a through model <code class=\"docutils literal notranslate\">AuthorBook</code> with a new field\n<code class=\"docutils literal notranslate\">is_primary</code>, like so:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.db</span> <span class=\"kn\">import</span> migrations<span class=\"p\">,</span> models\n<span class=\"kn\">import</span> <span class=\"nn\">django.db.models.deletion</span>\n\n\n<span class=\"k\">class</span> <span class=\"nc\">Migration</span><span class=\"p\">(</span>migrations<span class=\"o\">.</span>Migration<span class=\"p\">):</span>\n    dependencies <span class=\"o\">=</span> <span class=\"p\">[</span>\n        <span class=\"p\">(</span><span class=\"s2\">&quot;core&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;0001_initial&quot;</span><span class=\"p\">),</span>\n    <span class=\"p\">]</span>\n\n    operations <span class=\"o\">=</span> <span class=\"p\">[</span>\n        migrations<span class=\"o\">.</span>SeparateDatabaseAndState<span class=\"p\">(</span>\n            database_operations<span class=\"o\">=</span><span class=\"p\">[</span>\n                <span class=\"c1\"># Old table name from checking with sqlmigrate, new table</span>\n                <span class=\"c1\"># name from AuthorBook._meta.db_table.</span>\n                migrations<span class=\"o\">.</span>RunSQL<span class=\"p\">(</span>\n                    sql<span class=\"o\">=</span><span class=\"s2\">&quot;ALTER TABLE core_book_authors RENAME TO core_authorbook&quot;</span><span class=\"p\">,</span>\n                    reverse_sql<span class=\"o\">=</span><span class=\"s2\">&quot;ALTER TABLE core_authorbook RENAME TO core_book_authors&quot;</span><span class=\"p\">,</span>\n                <span class=\"p\">),</span>\n            <span class=\"p\">],</span>\n            state_operations<span class=\"o\">=</span><span class=\"p\">[</span>\n                migrations<span class=\"o\">.</span>CreateModel<span class=\"p\">(</span>\n                    name<span class=\"o\">=</span><span class=\"s2\">&quot;AuthorBook&quot;</span><span class=\"p\">,</span>\n                    fields<span class=\"o\">=</span><span class=\"p\">[</span>\n                        <span class=\"p\">(</span>\n                            <span class=\"s2\">&quot;id&quot;</span><span class=\"p\">,</span>\n                            models<span class=\"o\">.</span>AutoField<span class=\"p\">(</span>\n                                auto_created<span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span>\n                                primary_key<span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span>\n                                serialize<span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">,</span>\n                                verbose_name<span class=\"o\">=</span><span class=\"s2\">&quot;ID&quot;</span><span class=\"p\">,</span>\n                            <span class=\"p\">),</span>\n                        <span class=\"p\">),</span>\n                        <span class=\"p\">(</span>\n                            <span class=\"s2\">&quot;author&quot;</span><span class=\"p\">,</span>\n                            models<span class=\"o\">.</span>ForeignKey<span class=\"p\">(</span>\n                                on_delete<span class=\"o\">=</span>django<span class=\"o\">.</span>db<span class=\"o\">.</span>models<span class=\"o\">.</span>deletion<span class=\"o\">.</span>DO_NOTHING<span class=\"p\">,</span>\n                                to<span class=\"o\">=</span><span class=\"s2\">&quot;core.Author&quot;</span><span class=\"p\">,</span>\n                            <span class=\"p\">),</span>\n                        <span class=\"p\">),</span>\n                        <span class=\"p\">(</span>\n                            <span class=\"s2\">&quot;book&quot;</span><span class=\"p\">,</span>\n                            models<span class=\"o\">.</span>ForeignKey<span class=\"p\">(</span>\n                                on_delete<span class=\"o\">=</span>django<span class=\"o\">.</span>db<span class=\"o\">.</span>models<span class=\"o\">.</span>deletion<span class=\"o\">.</span>DO_NOTHING<span class=\"p\">,</span>\n                                to<span class=\"o\">=</span><span class=\"s2\">&quot;core.Book&quot;</span><span class=\"p\">,</span>\n                            <span class=\"p\">),</span>\n                        <span class=\"p\">),</span>\n                    <span class=\"p\">],</span>\n                <span class=\"p\">),</span>\n                migrations<span class=\"o\">.</span>AlterField<span class=\"p\">(</span>\n                    model_name<span class=\"o\">=</span><span class=\"s2\">&quot;book&quot;</span><span class=\"p\">,</span>\n                    name<span class=\"o\">=</span><span class=\"s2\">&quot;authors&quot;</span><span class=\"p\">,</span>\n                    field<span class=\"o\">=</span>models<span class=\"o\">.</span>ManyToManyField<span class=\"p\">(</span>\n                        to<span class=\"o\">=</span><span class=\"s2\">&quot;core.Author&quot;</span><span class=\"p\">,</span>\n                        through<span class=\"o\">=</span><span class=\"s2\">&quot;core.AuthorBook&quot;</span><span class=\"p\">,</span>\n                    <span class=\"p\">),</span>\n                <span class=\"p\">),</span>\n            <span class=\"p\">],</span>\n        <span class=\"p\">),</span>\n        migrations<span class=\"o\">.</span>AddField<span class=\"p\">(</span>\n            model_name<span class=\"o\">=</span><span class=\"s2\">&quot;authorbook&quot;</span><span class=\"p\">,</span>\n            name<span class=\"o\">=</span><span class=\"s2\">&quot;is_primary&quot;</span><span class=\"p\">,</span>\n            field<span class=\"o\">=</span>models<span class=\"o\">.</span>BooleanField<span class=\"p\">(</span>default<span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">),</span>\n        <span class=\"p\">),</span>\n    <span class=\"p\">]</span>\n</code></pre></div>\n</section>\n<section id=\"changing-an-unmanaged-model-to-managed\">\n<h2>Changing an unmanaged model to managed<a class=\"heading-anchor\" href=\"#changing-an-unmanaged-model-to-managed\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>If you want to change an unmanaged model (<a class=\"reference internal\" href=\"/en/5.0/ref/models/options/#django.db.models.Options.managed\" title=\"django.db.models.Options.managed\"><code class=\"xref py py-attr docutils literal notranslate\">managed=False</code></a>) to managed, you must remove\n<code class=\"docutils literal notranslate\">managed=False</code> and generate a migration before making other schema-related\nchanges to the model, since schema changes that appear in the migration that\ncontains the operation to change <code class=\"docutils literal notranslate\">Meta.managed</code> may not be applied.</p>\n</section>","rootId":"how-to-create-database-migrations","toc":[{"title":"Data migrations and multiple databases","anchor":"data-migrations-and-multiple-databases","children":[]},{"title":"Migrations that add unique fields","anchor":"migrations-that-add-unique-fields","children":[{"title":"Non-atomic migrations","anchor":"non-atomic-migrations","children":[]}]},{"title":"Controlling the order of migrations","anchor":"controlling-the-order-of-migrations","children":[]},{"title":"Migrating data between third-party apps","anchor":"migrating-data-between-third-party-apps","children":[]},{"title":"Changing a ManyToManyField to use a through model","anchor":"changing-a-manytomanyfield-to-use-a-through-model","children":[]},{"title":"Changing an unmanaged model to managed","anchor":"changing-an-unmanaged-model-to-managed","children":[]}],"breadcrumbs":[{"docname":"howto/index","title":"“How-to” guides","url":"/en/5.0/howto/"}],"prev":{"docname":"howto/windows","title":"How to install Django on Windows","url":"/en/5.0/howto/windows/"},"next":{"docname":"howto/delete-app","title":"How to delete a Django application","url":"/en/5.0/howto/delete-app/"},"formats":{"html":"/en/5.0/howto/writing-migrations/","markdown":"/en/5.0/howto/writing-migrations.md","json":"/en/5.0/howto/writing-migrations.json"},"source":"https://github.com/django/django/blob/stable/5.0.x/docs/howto/writing-migrations.txt","official":"https://docs.djangoproject.com/en/5.0/howto/writing-migrations/","inVersions":["dev","6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0","2.2","2.1","2.0","1.11","1.10","1.9","1.8"],"inLocales":["en","zh-hans","fr","ja","id","it","pt-br","ko","es","el","pl"]}