{"title":"Écriture de migrations de base de données","version":"2.1","locale":"fr","docname":"howto/writing-migrations","url":"/fr/2.1/howto/writing-migrations/","canonical":"https://djangodocs.dev/fr/2.1/howto/writing-migrations/","summary":"Ce document présente la façon de structurer et d’écrire des migrations de base de données pour différents scénarios auxquels vous pourriez être confrontés. Pour du…","html":"<h1>Écriture de migrations de base de données<a class=\"heading-anchor\" href=\"#writing-database-migrations\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>Ce document présente la façon de structurer et d’écrire des migrations de base de données pour différents scénarios auxquels vous pourriez être confrontés. Pour du contenu introductif aux migrations, consultez le <a class=\"reference internal\" href=\"/fr/2.1/topics/migrations/\"><span class=\"doc\">guide thématique</span></a>.</p>\n<section id=\"data-migrations-and-multiple-databases\">\n<span id=\"id1\"></span><h2>Migrations de données et bases de données multiples<a class=\"heading-anchor\" href=\"#data-migrations-and-multiple-databases\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Lorsque vous utilisez plusieurs bases de données, il peut être nécessaire de déterminer si une migration doit être appliquée à une certaine base de données. Par exemple, il est possible qu’une migration ne doive s’appliquer qu’à <strong>une seule</strong> base de données.</p>\n<p>Pour faire cela, il est possible de se baser sur l’alias de base de données de la connexion dans une opération <code class=\"docutils literal notranslate\"><span class=\"pre\">RunPython</span></code> en consultant l’attribut <code class=\"docutils literal notranslate\"><span class=\"pre\">schema_editor.connection.alias</span></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=\"w\"> </span><span class=\"nn\">django.db</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">migrations</span>\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">forwards</span><span class=\"p\">(</span><span class=\"n\">apps</span><span class=\"p\">,</span> <span class=\"n\">schema_editor</span><span class=\"p\">):</span>\n    <span class=\"k\">if</span> <span class=\"n\">schema_editor</span><span class=\"o\">.</span><span class=\"n\">connection</span><span class=\"o\">.</span><span class=\"n\">alias</span> <span class=\"o\">!=</span> <span class=\"s1\">&#39;default&#39;</span><span class=\"p\">:</span>\n        <span class=\"k\">return</span>\n    <span class=\"c1\"># Your migration code goes here</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Migration</span><span class=\"p\">(</span><span class=\"n\">migrations</span><span class=\"o\">.</span><span class=\"n\">Migration</span><span class=\"p\">):</span>\n\n    <span class=\"n\">dependencies</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n        <span class=\"c1\"># Dependencies to other migrations</span>\n    <span class=\"p\">]</span>\n\n    <span class=\"n\">operations</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n        <span class=\"n\">migrations</span><span class=\"o\">.</span><span class=\"n\">RunPython</span><span class=\"p\">(</span><span class=\"n\">forwards</span><span class=\"p\">),</span>\n    <span class=\"p\">]</span>\n</code></pre></div>\n<p>Vous pouvez également fournir des indications qui seront transmises à la méthode <a class=\"reference internal\" href=\"/fr/2.1/topics/db/multi-db/#allow_migrate\" title=\"allow_migrate\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">allow_migrate()</span></code></a> des routeurs de base de données, dans <code class=\"docutils literal notranslate\"><span class=\"pre\">**hints</span></code>:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\">myapp/dbrouters.py</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=\"w\"> </span><span class=\"nc\">MyRouter</span><span class=\"p\">:</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">allow_migrate</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">db</span><span class=\"p\">,</span> <span class=\"n\">app_label</span><span class=\"p\">,</span> <span class=\"n\">model_name</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">hints</span><span class=\"p\">):</span>\n        <span class=\"k\">if</span> <span class=\"s1\">&#39;target_db&#39;</span> <span class=\"ow\">in</span> <span class=\"n\">hints</span><span class=\"p\">:</span>\n            <span class=\"k\">return</span> <span class=\"n\">db</span> <span class=\"o\">==</span> <span class=\"n\">hints</span><span class=\"p\">[</span><span class=\"s1\">&#39;target_db&#39;</span><span class=\"p\">]</span>\n        <span class=\"k\">return</span> <span class=\"kc\">True</span>\n</code></pre></figure>\n<p>Puis, pour s’appuyer sur ce code dans une migration, procédez comme suit :</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=\"w\"> </span><span class=\"nn\">django.db</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">migrations</span>\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">forwards</span><span class=\"p\">(</span><span class=\"n\">apps</span><span class=\"p\">,</span> <span class=\"n\">schema_editor</span><span class=\"p\">):</span>\n    <span class=\"c1\"># Your migration code goes here</span>\n    <span class=\"o\">...</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Migration</span><span class=\"p\">(</span><span class=\"n\">migrations</span><span class=\"o\">.</span><span class=\"n\">Migration</span><span class=\"p\">):</span>\n\n    <span class=\"n\">dependencies</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n        <span class=\"c1\"># Dependencies to other migrations</span>\n    <span class=\"p\">]</span>\n\n    <span class=\"n\">operations</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n        <span class=\"n\">migrations</span><span class=\"o\">.</span><span class=\"n\">RunPython</span><span class=\"p\">(</span><span class=\"n\">forwards</span><span class=\"p\">,</span> <span class=\"n\">hints</span><span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s1\">&#39;target_db&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;default&#39;</span><span class=\"p\">}),</span>\n    <span class=\"p\">]</span>\n</code></pre></div>\n<p>Si votre opération <code class=\"docutils literal notranslate\"><span class=\"pre\">RunPython</span></code> ou <code class=\"docutils literal notranslate\"><span class=\"pre\">RunSQL</span></code> n’affecte qu’un seul modèle, il est de bon aloi de passer <code class=\"docutils literal notranslate\"><span class=\"pre\">model_name</span></code> comme indicateur pour la rendre aussi transparente que possible par rapport au routeur. C’est particulièrement important pour les applications tierces et réutilisables.</p>\n</section>\n<section id=\"migrations-that-add-unique-fields\">\n<h2>Migrations ajoutant des champs uniques<a class=\"heading-anchor\" href=\"#migrations-that-add-unique-fields\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>L’application d’une « simple » migration qui ajoute un champ unique non nul à une table qui contient déjà des lignes va produire une erreur car la valeur utilisée pour remplir les champs existants n’est générée qu’une seule fois, ce qui va à l’encontre de la contrainte d’unicité.</p>\n<p>Il est donc nécessaire de suivre les étapes suivantes. Dans cet exemple, nous allons ajouter un champ non nul <a class=\"reference internal\" href=\"/fr/2.1/ref/models/fields/#django.db.models.UUIDField\" title=\"django.db.models.UUIDField\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">UUIDField</span></code></a> avec une valeur par défaut. Modifiez le champ adéquat en fonction de vos propres besoins.</p>\n<ul>\n<li><p>Ajoutez le champ à votre modèle avec les paramètres <code class=\"docutils literal notranslate\"><span class=\"pre\">default=uuid.uuid4</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">unique=True</span></code> (choisissez une valeur par défaut adéquate au type de champ que vous ajoutez).</p></li>\n<li><p>Lancez la commande <a class=\"reference internal\" href=\"/fr/2.1/ref/django-admin/#django-admin-makemigrations\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">makemigrations</span></code></a>. Cela devrait générer une migration contenant une opération <code class=\"docutils literal notranslate\"><span class=\"pre\">AddField</span></code>.</p></li>\n<li><p>Générez deux fichiers de migration vides pour la même application en exécutant deux fois <code class=\"docutils literal notranslate\"><span class=\"pre\">makemigrations</span> <span class=\"pre\">monapp</span> <span class=\"pre\">--empty</span></code>. Nous avons renommé les fichiers de migration dans les exemples ci-dessous pour leur donner des noms plus explicites.</p></li>\n<li><p>Copiez l’opération <code class=\"docutils literal notranslate\"><span class=\"pre\">AddField</span></code> à partir de la migration auto-générée (le premier des trois nouveaux fichiers) vers la dernière migration, modifiez <code class=\"docutils literal notranslate\"><span class=\"pre\">AddField</span></code> en <code class=\"docutils literal notranslate\"><span class=\"pre\">AlterField</span></code> et ajoutez des importations pour <code class=\"docutils literal notranslate\"><span class=\"pre\">uuid</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">models</span></code>. Par exemple :</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\">0006_remove_uuid_null.py</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=\"w\"> </span><span class=\"nn\">django.db</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">migrations</span><span class=\"p\">,</span> <span class=\"n\">models</span>\n<span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">uuid</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Migration</span><span class=\"p\">(</span><span class=\"n\">migrations</span><span class=\"o\">.</span><span class=\"n\">Migration</span><span class=\"p\">):</span>\n\n    <span class=\"n\">dependencies</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n        <span class=\"p\">(</span><span class=\"s1\">&#39;myapp&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;0005_populate_uuid_values&#39;</span><span class=\"p\">),</span>\n    <span class=\"p\">]</span>\n\n    <span class=\"n\">operations</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n        <span class=\"n\">migrations</span><span class=\"o\">.</span><span class=\"n\">AlterField</span><span class=\"p\">(</span>\n            <span class=\"n\">model_name</span><span class=\"o\">=</span><span class=\"s1\">&#39;mymodel&#39;</span><span class=\"p\">,</span>\n            <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;uuid&#39;</span><span class=\"p\">,</span>\n            <span class=\"n\">field</span><span class=\"o\">=</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">UUIDField</span><span class=\"p\">(</span><span class=\"n\">default</span><span class=\"o\">=</span><span class=\"n\">uuid</span><span class=\"o\">.</span><span class=\"n\">uuid4</span><span class=\"p\">,</span> <span class=\"n\">unique</span><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>Modifiez le premier fichier de migration. La classe de migration générée devrait ressembler à ceci :</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\">0004_add_uuid_field.py</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=\"w\"> </span><span class=\"nc\">Migration</span><span class=\"p\">(</span><span class=\"n\">migrations</span><span class=\"o\">.</span><span class=\"n\">Migration</span><span class=\"p\">):</span>\n\n    <span class=\"n\">dependencies</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n        <span class=\"p\">(</span><span class=\"s1\">&#39;myapp&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;0003_auto_20150129_1705&#39;</span><span class=\"p\">),</span>\n    <span class=\"p\">]</span>\n\n    <span class=\"n\">operations</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n        <span class=\"n\">migrations</span><span class=\"o\">.</span><span class=\"n\">AddField</span><span class=\"p\">(</span>\n            <span class=\"n\">model_name</span><span class=\"o\">=</span><span class=\"s1\">&#39;mymodel&#39;</span><span class=\"p\">,</span>\n            <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;uuid&#39;</span><span class=\"p\">,</span>\n            <span class=\"n\">field</span><span class=\"o\">=</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">UUIDField</span><span class=\"p\">(</span><span class=\"n\">default</span><span class=\"o\">=</span><span class=\"n\">uuid</span><span class=\"o\">.</span><span class=\"n\">uuid4</span><span class=\"p\">,</span> <span class=\"n\">unique</span><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>Modifiez <code class=\"docutils literal notranslate\"><span class=\"pre\">unique=True</span></code> en <code class=\"docutils literal notranslate\"><span class=\"pre\">null=True</span></code>, ce qui créera le champ intermédiaire pouvant contenir la valeur <code class=\"docutils literal notranslate\"><span class=\"pre\">null</span></code> et va différer la création de la contrainte d’unicité en attendant que nous ayons terminé de remplir les valeurs uniques pour chaque ligne.</p>\n</li>\n<li><p>Dans le premier fichier de mgiration vide, ajoutez une opération <a class=\"reference internal\" href=\"/fr/2.1/ref/migration-operations/#django.db.migrations.operations.RunPython\" title=\"django.db.migrations.operations.RunPython\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">RunPython</span></code></a> ou <a class=\"reference internal\" href=\"/fr/2.1/ref/migration-operations/#django.db.migrations.operations.RunSQL\" title=\"django.db.migrations.operations.RunSQL\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">RunSQL</span></code></a> pour générer une valeur unique (UUID dans l’exemple) pour chaque ligne existante. Ajoutez aussi une importation pour <code class=\"docutils literal notranslate\"><span class=\"pre\">uuid</span></code>. Par exemple :</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\">0005_populate_uuid_values.py</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=\"w\"> </span><span class=\"nn\">django.db</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">migrations</span>\n<span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">uuid</span>\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">gen_uuid</span><span class=\"p\">(</span><span class=\"n\">apps</span><span class=\"p\">,</span> <span class=\"n\">schema_editor</span><span class=\"p\">):</span>\n    <span class=\"n\">MyModel</span> <span class=\"o\">=</span> <span class=\"n\">apps</span><span class=\"o\">.</span><span class=\"n\">get_model</span><span class=\"p\">(</span><span class=\"s1\">&#39;myapp&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;MyModel&#39;</span><span class=\"p\">)</span>\n    <span class=\"k\">for</span> <span class=\"n\">row</span> <span class=\"ow\">in</span> <span class=\"n\">MyModel</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">all</span><span class=\"p\">():</span>\n        <span class=\"n\">row</span><span class=\"o\">.</span><span class=\"n\">uuid</span> <span class=\"o\">=</span> <span class=\"n\">uuid</span><span class=\"o\">.</span><span class=\"n\">uuid4</span><span class=\"p\">()</span>\n        <span class=\"n\">row</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">(</span><span class=\"n\">update_fields</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"s1\">&#39;uuid&#39;</span><span class=\"p\">])</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Migration</span><span class=\"p\">(</span><span class=\"n\">migrations</span><span class=\"o\">.</span><span class=\"n\">Migration</span><span class=\"p\">):</span>\n\n    <span class=\"n\">dependencies</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n        <span class=\"p\">(</span><span class=\"s1\">&#39;myapp&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;0004_add_uuid_field&#39;</span><span class=\"p\">),</span>\n    <span class=\"p\">]</span>\n\n    <span class=\"n\">operations</span> <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        <span class=\"n\">migrations</span><span class=\"o\">.</span><span class=\"n\">RunPython</span><span class=\"p\">(</span><span class=\"n\">gen_uuid</span><span class=\"p\">,</span> <span class=\"n\">reverse_code</span><span class=\"o\">=</span><span class=\"n\">migrations</span><span class=\"o\">.</span><span class=\"n\">RunPython</span><span class=\"o\">.</span><span class=\"n\">noop</span><span class=\"p\">),</span>\n    <span class=\"p\">]</span>\n</code></pre></figure>\n</li>\n<li><p>Vous pouvez maintenant appliquer les migrations comme d’habitude avec la commande <a class=\"reference internal\" href=\"/fr/2.1/ref/django-admin/#django-admin-migrate\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">migrate</span></code></a>.</p>\n<p>Notez qu’il existe un conflit de concurrence si vous permettez de créer des objets lorsque cette migration se déroule. Les objets créés après l’opération <code class=\"docutils literal notranslate\"><span class=\"pre\">AddField</span></code> mais avant <code class=\"docutils literal notranslate\"><span class=\"pre\">RunPython</span></code> verront leur valeur originale <code class=\"docutils literal notranslate\"><span class=\"pre\">uuid</span></code> écrasée.</p>\n</li>\n</ul>\n<section id=\"non-atomic-migrations\">\n<span id=\"id2\"></span><h3>Migrations non atomiques<a class=\"heading-anchor\" href=\"#non-atomic-migrations\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Avec les bases de données qui gèrent les transactions pour les instructions de définition de schéma (SQLite and PostgreSQL), les migrations s’exécuteront par défaut dans une transaction. Pour des cas d’utilisation tels que l’application de migrations de données sur des grosses tables, il est possible d’empêcher qu’une migration s’exécute dans une transaction en définissant l’attribut <code class=\"docutils literal notranslate\"><span class=\"pre\">atomic</span></code> à <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></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=\"w\"> </span><span class=\"nn\">django.db</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">migrations</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Migration</span><span class=\"p\">(</span><span class=\"n\">migrations</span><span class=\"o\">.</span><span class=\"n\">Migration</span><span class=\"p\">):</span>\n    <span class=\"n\">atomic</span> <span class=\"o\">=</span> <span class=\"kc\">False</span>\n</code></pre></div>\n<p>Dans une telle migration, toutes les opérations sont lancées sans transaction. Il est possible d’exécuter certaines parties de la migration dans une transaction en utilisant <a class=\"reference internal\" href=\"/fr/2.1/topics/db/transactions/#django.db.transaction.atomic\" title=\"django.db.transaction.atomic\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">atomic()</span></code></a> ou en passant <code class=\"docutils literal notranslate\"><span class=\"pre\">atomic=True</span></code> à <code class=\"docutils literal notranslate\"><span class=\"pre\">RunPython</span></code>.</p>\n<p>Voici un exemple d’une migration de données non atomique qui met à jour une grosse table en lots plus petits :</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=\"w\"> </span><span class=\"nn\">uuid</span>\n\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">migrations</span><span class=\"p\">,</span> <span class=\"n\">transaction</span>\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">gen_uuid</span><span class=\"p\">(</span><span class=\"n\">apps</span><span class=\"p\">,</span> <span class=\"n\">schema_editor</span><span class=\"p\">):</span>\n    <span class=\"n\">MyModel</span> <span class=\"o\">=</span> <span class=\"n\">apps</span><span class=\"o\">.</span><span class=\"n\">get_model</span><span class=\"p\">(</span><span class=\"s1\">&#39;myapp&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;MyModel&#39;</span><span class=\"p\">)</span>\n    <span class=\"k\">while</span> <span class=\"n\">MyModel</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">uuid__isnull</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">exists</span><span class=\"p\">():</span>\n        <span class=\"k\">with</span> <span class=\"n\">transaction</span><span class=\"o\">.</span><span class=\"n\">atomic</span><span class=\"p\">():</span>\n            <span class=\"k\">for</span> <span class=\"n\">row</span> <span class=\"ow\">in</span> <span class=\"n\">MyModel</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">uuid__isnull</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)[:</span><span class=\"mi\">1000</span><span class=\"p\">]:</span>\n                <span class=\"n\">row</span><span class=\"o\">.</span><span class=\"n\">uuid</span> <span class=\"o\">=</span> <span class=\"n\">uuid</span><span class=\"o\">.</span><span class=\"n\">uuid4</span><span class=\"p\">()</span>\n                <span class=\"n\">row</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">()</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Migration</span><span class=\"p\">(</span><span class=\"n\">migrations</span><span class=\"o\">.</span><span class=\"n\">Migration</span><span class=\"p\">):</span>\n    <span class=\"n\">atomic</span> <span class=\"o\">=</span> <span class=\"kc\">False</span>\n\n    <span class=\"n\">operations</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n        <span class=\"n\">migrations</span><span class=\"o\">.</span><span class=\"n\">RunPython</span><span class=\"p\">(</span><span class=\"n\">gen_uuid</span><span class=\"p\">),</span>\n    <span class=\"p\">]</span>\n</code></pre></div>\n<p>The <code class=\"docutils literal notranslate\"><span class=\"pre\">atomic</span></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>Contrôle de l’ordre des migrations<a class=\"heading-anchor\" href=\"#controlling-the-order-of-migrations\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Django détermine l’ordre dans lequel les migrations doivent être appliquées non pas selon le nom de fichier des migrations, mais en construisant un graphe basé sur deux propriétés de la classe <code class=\"docutils literal notranslate\"><span class=\"pre\">Migration</span></code>: <code class=\"docutils literal notranslate\"><span class=\"pre\">dependencies</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">run_before</span></code>.</p>\n<p>Si vous avez déjà utilisé la commande <a class=\"reference internal\" href=\"/fr/2.1/ref/django-admin/#django-admin-makemigrations\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">makemigrations</span></code></a>, vous avez probablement vu la présence de <code class=\"docutils literal notranslate\"><span class=\"pre\">dependencies</span></code> car les migrations créées automatiquement définissent cet attribut dans le cadre du processus de création.</p>\n<p>La propriété <code class=\"docutils literal notranslate\"><span class=\"pre\">dependencies</span></code> est déclarée comme ceci :</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=\"w\"> </span><span class=\"nn\">django.db</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">migrations</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Migration</span><span class=\"p\">(</span><span class=\"n\">migrations</span><span class=\"o\">.</span><span class=\"n\">Migration</span><span class=\"p\">):</span>\n\n    <span class=\"n\">dependencies</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n        <span class=\"p\">(</span><span class=\"s1\">&#39;myapp&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;0123_the_previous_migration&#39;</span><span class=\"p\">),</span>\n    <span class=\"p\">]</span>\n</code></pre></div>\n<p>Cela suffit en général, mais de temps à autre, il peut être nécessaire de s’assurer que la migration s’exécute <em>avant</em> une autre. C’est par exemple utile pour que des migrations d’applications tierces s’exécutent <em>après</em> celles du modèle de remplacement <a class=\"reference internal\" href=\"/fr/2.1/ref/settings/#std-setting-AUTH_USER_MODEL\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">AUTH_USER_MODEL</span></code></a>.</p>\n<p>Pour faire cela, placez toutes les migrations qui doivent dépendre des vôtres dans l’attribut <code class=\"docutils literal notranslate\"><span class=\"pre\">run_before</span></code> de votre classe <code class=\"docutils literal notranslate\"><span class=\"pre\">Migration</span></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=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Migration</span><span class=\"p\">(</span><span class=\"n\">migrations</span><span class=\"o\">.</span><span class=\"n\">Migration</span><span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n\n    <span class=\"n\">run_before</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n        <span class=\"p\">(</span><span class=\"s1\">&#39;third_party_app&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;0001_do_awesome&#39;</span><span class=\"p\">),</span>\n    <span class=\"p\">]</span>\n</code></pre></div>\n<p>Privilégiez autant que possible l’usage de <code class=\"docutils literal notranslate\"><span class=\"pre\">dependencies</span></code> par rapport à <code class=\"docutils literal notranslate\"><span class=\"pre\">run_before</span></code>. <code class=\"docutils literal notranslate\"><span class=\"pre\">run_before</span></code> ne devrait être utilisé que dans le cas où il n’est pas souhaitable ou pas possible de définir <code class=\"docutils literal notranslate\"><span class=\"pre\">dependencies</span></code> dans la migration que vous voulez faire exécuter après celle que vous êtes en train d’écrire.</p>\n</section>\n<section id=\"migrating-data-between-third-party-apps\">\n<h2>Migration de données entre applications tierces<a class=\"heading-anchor\" href=\"#migrating-data-between-third-party-apps\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Vous pouvez utiliser une migration de données pour déplacer des données d’une application tierce à une autre.</p>\n<p>Si vous prévoyez d’enlever l’ancienne application plus tard, il vous faudra définir la propriété <code class=\"docutils literal notranslate\"><span class=\"pre\">dependencies</span></code> en fonction de la présence de l’ancienne application dans les applications installées. Sinon, des dépendances vont manquer au moment de désinstaller l’ancienne application. De même, il faudra intercepter <a class=\"reference external\" href=\"https://docs.python.org/3/library/exceptions.html#LookupError\" title=\"(disponible dans Python v3.14)\"><code class=\"xref py py-exc docutils literal notranslate\"><span class=\"pre\">LookupError</span></code></a> dans l’appel à <code class=\"docutils literal notranslate\"><span class=\"pre\">apps.get_model()</span></code> qui récupère les modèles de l’ancienne application. Cette approche vous permet de déployer votre projet partout sans devoir d’abord installer puis désinstaller l’ancienne application.</p>\n<p>Voici un exemple de migration :</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\">myapp/migrations/0124_move_old_app_to_new_app.py</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=\"w\"> </span><span class=\"nn\">django.apps</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">apps</span> <span class=\"k\">as</span> <span class=\"n\">global_apps</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">migrations</span>\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">forwards</span><span class=\"p\">(</span><span class=\"n\">apps</span><span class=\"p\">,</span> <span class=\"n\">schema_editor</span><span class=\"p\">):</span>\n    <span class=\"k\">try</span><span class=\"p\">:</span>\n        <span class=\"n\">OldModel</span> <span class=\"o\">=</span> <span class=\"n\">apps</span><span class=\"o\">.</span><span class=\"n\">get_model</span><span class=\"p\">(</span><span class=\"s1\">&#39;old_app&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;OldModel&#39;</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    <span class=\"n\">NewModel</span> <span class=\"o\">=</span> <span class=\"n\">apps</span><span class=\"o\">.</span><span class=\"n\">get_model</span><span class=\"p\">(</span><span class=\"s1\">&#39;new_app&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;NewModel&#39;</span><span class=\"p\">)</span>\n    <span class=\"n\">NewModel</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">bulk_create</span><span class=\"p\">(</span>\n        <span class=\"n\">NewModel</span><span class=\"p\">(</span><span class=\"n\">new_attribute</span><span class=\"o\">=</span><span class=\"n\">old_object</span><span class=\"o\">.</span><span class=\"n\">old_attribute</span><span class=\"p\">)</span>\n        <span class=\"k\">for</span> <span class=\"n\">old_object</span> <span class=\"ow\">in</span> <span class=\"n\">OldModel</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">all</span><span class=\"p\">()</span>\n    <span class=\"p\">)</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Migration</span><span class=\"p\">(</span><span class=\"n\">migrations</span><span class=\"o\">.</span><span class=\"n\">Migration</span><span class=\"p\">):</span>\n    <span class=\"n\">operations</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n        <span class=\"n\">migrations</span><span class=\"o\">.</span><span class=\"n\">RunPython</span><span class=\"p\">(</span><span class=\"n\">forwards</span><span class=\"p\">,</span> <span class=\"n\">migrations</span><span class=\"o\">.</span><span class=\"n\">RunPython</span><span class=\"o\">.</span><span class=\"n\">noop</span><span class=\"p\">),</span>\n    <span class=\"p\">]</span>\n    <span class=\"n\">dependencies</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n        <span class=\"p\">(</span><span class=\"s1\">&#39;myapp&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;0123_the_previous_migration&#39;</span><span class=\"p\">),</span>\n        <span class=\"p\">(</span><span class=\"s1\">&#39;new_app&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;0001_initial&#39;</span><span class=\"p\">),</span>\n    <span class=\"p\">]</span>\n\n    <span class=\"k\">if</span> <span class=\"n\">global_apps</span><span class=\"o\">.</span><span class=\"n\">is_installed</span><span class=\"p\">(</span><span class=\"s1\">&#39;old_app&#39;</span><span class=\"p\">):</span>\n        <span class=\"n\">dependencies</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">((</span><span class=\"s1\">&#39;old_app&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;0001_initial&#39;</span><span class=\"p\">))</span>\n</code></pre></figure>\n<p>Considérez également ce qui va se passer lorsque la migration sera désappliquée. Vous pouvez soit ne rien faire (comme dans l’exemple ci-dessus), soit enlever certaines ou toutes les données de la nouvelle application. Ajustez le second paramètre de l’opération <a class=\"reference internal\" href=\"/fr/2.1/ref/migration-operations/#django.db.migrations.operations.RunPython\" title=\"django.db.migrations.operations.RunPython\"><code class=\"xref py py-mod docutils literal notranslate\"><span class=\"pre\">RunPython</span></code></a> en fonction de votre choix.</p>\n</section>\n<section id=\"changing-an-unmanaged-model-to-managed\">\n<h2>Modification d’un modèle non géré en géré<a class=\"heading-anchor\" href=\"#changing-an-unmanaged-model-to-managed\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Si vous souhaitez modifier un modèle non géré (<a class=\"reference internal\" href=\"/fr/2.1/ref/models/options/#django.db.models.Options.managed\" title=\"django.db.models.Options.managed\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">managed=False</span></code></a>) en modèle géré, vous devez enlever <code class=\"docutils literal notranslate\"><span class=\"pre\">managed=False</span></code> et générer une migration avant de faire d’autres modifications de schéma du modèle, car les modifications de schéma figurant dans la même migration que celle contenant l’opération de modification de  <code class=\"docutils literal notranslate\"><span class=\"pre\">Meta.managed</span></code> pourraient ne pas être appliquées.</p>\n</section>","rootId":"writing-database-migrations","toc":[{"title":"Migrations de données et bases de données multiples","anchor":"data-migrations-and-multiple-databases","children":[]},{"title":"Migrations ajoutant des champs uniques","anchor":"migrations-that-add-unique-fields","children":[{"title":"Migrations non atomiques","anchor":"non-atomic-migrations","children":[]}]},{"title":"Contrôle de l’ordre des migrations","anchor":"controlling-the-order-of-migrations","children":[]},{"title":"Migration de données entre applications tierces","anchor":"migrating-data-between-third-party-apps","children":[]},{"title":"Modification d’un modèle non géré en géré","anchor":"changing-an-unmanaged-model-to-managed","children":[]}],"breadcrumbs":[{"docname":"howto/index","title":"Guides pratiques","url":"/fr/2.1/howto/"}],"prev":{"docname":"howto/windows","title":"Comment installer Django avec Windows","url":"/fr/2.1/howto/windows/"},"next":{"docname":"faq/index","title":"FAQ Django","url":"/fr/2.1/faq/"},"formats":{"html":"/fr/2.1/howto/writing-migrations/","markdown":"/fr/2.1/howto/writing-migrations.md","json":"/fr/2.1/howto/writing-migrations.json"},"source":"https://github.com/django/django/blob/stable/2.1.x/docs/howto/writing-migrations.txt","official":"https://docs.djangoproject.com/fr/2.1/howto/writing-migrations/","inVersions":["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"],"inLocales":["en","zh-hans","fr","ja","id","pt-br","ko","es","el","pl"]}