{"title":"Bases de données multiples","version":"5.0","locale":"fr","docname":"topics/db/multi-db","url":"/fr/5.0/topics/db/multi-db/","canonical":"https://djangodocs.dev/fr/5.0/topics/db/multi-db/","summary":"Ce guide thématique décrit la prise en charge de plusieurs bases de données par Django. La plupart de la documentation de Django suppose que vous travaillez avec…","html":"<h1>Bases de données multiples<a class=\"heading-anchor\" href=\"#multiple-databases\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>Ce guide thématique décrit la prise en charge de plusieurs bases de données par Django. La plupart de la documentation de Django suppose que vous travaillez avec une seule base de données. Si vous avez besoin de travailler avec plusieurs bases de données, il sera nécessaire de procéder à quelques configurations supplémentaires.</p>\n<aside class=\"admonition admonition-seealso\">\n<p class=\"admonition-title\">Voir aussi</p>\n<p>Consultez <a class=\"reference internal\" href=\"/fr/5.0/topics/testing/tools/#testing-multi-db\"><span class=\"std std-ref\">Prise en charge de plusieurs bases de données</span></a> pour des informations sur les tests avec plusieurs bases de données.</p>\n</aside>\n<section id=\"defining-your-databases\">\n<h2>Définition des bases de données<a class=\"heading-anchor\" href=\"#defining-your-databases\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>La première chose à faire lorsqu’on veut utiliser plus d’une base de données avec Django est de le renseigner au sujet des serveurs de base de données à utiliser. Cela se fait au niveau du réglage <a class=\"reference internal\" href=\"/fr/5.0/ref/settings/#std-setting-DATABASES\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">DATABASES</span></code></a>. Ce réglage fait correspondre des alias de bases de données, qui sont une manière de se référer à des bases de données spécifiques dans le code de Django, à un dictionnaire de réglages pour la connexion concernée. Les réglages du dictionnaire interne sont détaillés dans la documentation de <a class=\"reference internal\" href=\"/fr/5.0/ref/settings/#std-setting-DATABASES\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">DATABASES</span></code></a>.</p>\n<p>L’alias de base de données peut être librement choisi. Cependant, l’alias <code class=\"docutils literal notranslate\"><span class=\"pre\">default</span></code> a une signification spéciale. Django utilise la base de données ayant l’alias <code class=\"docutils literal notranslate\"><span class=\"pre\">default</span></code> lorsqu’aucune autre base de données n’a été sélectionnée.</p>\n<p>L’exemple suivant est un extrait de <code class=\"docutils literal notranslate\"><span class=\"pre\">settings.py</span></code> définissant deux bases de données, une base de données PostgreSQL par défaut et une base de données MySQL nommée <code class=\"docutils literal notranslate\"><span class=\"pre\">users</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=\"n\">DATABASES</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n    <span class=\"s2\">&quot;default&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n        <span class=\"s2\">&quot;NAME&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;app_data&quot;</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;ENGINE&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;django.db.backends.postgresql&quot;</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;USER&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;postgres_user&quot;</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;PASSWORD&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;s3krit&quot;</span><span class=\"p\">,</span>\n    <span class=\"p\">},</span>\n    <span class=\"s2\">&quot;users&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n        <span class=\"s2\">&quot;NAME&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;user_data&quot;</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;ENGINE&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;django.db.backends.mysql&quot;</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;USER&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;mysql_user&quot;</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;PASSWORD&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;priv4te&quot;</span><span class=\"p\">,</span>\n    <span class=\"p\">},</span>\n<span class=\"p\">}</span>\n</code></pre></div>\n<p>Si le concept d’une base de données par défaut n’a pas de sens dans le contexte de votre projet, vous devez vous efforcez de systématiquement indiquer la base de données à utiliser. Django exige qu’une base de données nommée  <code class=\"docutils literal notranslate\"><span class=\"pre\">default</span></code> soit définie, mais le dictionnaire des paramètres peut rester vierge s’il n’est pas utilisé. Pour faire cela, vous devez configurer <a class=\"reference internal\" href=\"/fr/5.0/ref/settings/#std-setting-DATABASE_ROUTERS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">DATABASE_ROUTERS</span></code></a> pour tous les modèles de vos applications, y compris ceux des applications « contrib » ou d’applications tierces que vous utilisez, afin qu’aucune requête ne soit dirigée vers la base de données par défaut. L’exemple suivant est un extrait de <code class=\"docutils literal notranslate\"><span class=\"pre\">settings.py</span></code> définissant deux bases de données spécifiques, avec l’entrée <code class=\"docutils literal notranslate\"><span class=\"pre\">default</span></code> volontairement laissée vide :</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=\"n\">DATABASES</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n    <span class=\"s2\">&quot;default&quot;</span><span class=\"p\">:</span> <span class=\"p\">{},</span>\n    <span class=\"s2\">&quot;users&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n        <span class=\"s2\">&quot;NAME&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;user_data&quot;</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;ENGINE&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;django.db.backends.mysql&quot;</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;USER&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;mysql_user&quot;</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;PASSWORD&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;superS3cret&quot;</span><span class=\"p\">,</span>\n    <span class=\"p\">},</span>\n    <span class=\"s2\">&quot;customers&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n        <span class=\"s2\">&quot;NAME&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;customer_data&quot;</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;ENGINE&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;django.db.backends.mysql&quot;</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;USER&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;mysql_cust&quot;</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;PASSWORD&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;veryPriv@ate&quot;</span><span class=\"p\">,</span>\n    <span class=\"p\">},</span>\n<span class=\"p\">}</span>\n</code></pre></div>\n<p>Si vous essayez d’accéder à une base de données qui n’y pas été définie dans le réglage <a class=\"reference internal\" href=\"/fr/5.0/ref/settings/#std-setting-DATABASES\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">DATABASES</span></code></a>, Django génère une exception <code class=\"docutils literal notranslate\"><span class=\"pre\">django.utils.connection.ConnectionDoesNotExist</span></code>.</p>\n</section>\n<section id=\"synchronizing-your-databases\">\n<span id=\"synchronizing-multiple-databases\"></span><h2>Synchronisation des bases de données<a class=\"heading-anchor\" href=\"#synchronizing-your-databases\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>La commande de gestion <a class=\"reference internal\" href=\"/fr/5.0/ref/django-admin/#django-admin-migrate\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">migrate</span></code></a> opère sur une seule base de données à la fois. Par défaut, elle agit sur la base de données <code class=\"docutils literal notranslate\"><span class=\"pre\">default</span></code>, mais en renseignant l’option <a class=\"reference internal\" href=\"/fr/5.0/ref/django-admin/#cmdoption-migrate-database\"><code class=\"xref std std-option docutils literal notranslate\"><span class=\"pre\">--database</span></code></a>, vous pouvez lui demander de synchroniser une autre base de données. Ainsi, pour synchroniser tous les modèles de toutes les bases de données dans le premier exemple ci-dessus, il faudrait exécuter :</p>\n<div class=\"code-block\" data-language=\"shell\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</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=\"Shell code\"><code>$<span class=\"w\"> </span>./manage.py<span class=\"w\"> </span>migrate\n$<span class=\"w\"> </span>./manage.py<span class=\"w\"> </span>migrate<span class=\"w\"> </span>--database<span class=\"o\">=</span>users\n</code></pre></div>\n<p>Si vous ne voulez pas que chaque application soit synchronisée vers une base de données particulière, vous pouvez définir un <a class=\"reference internal\" href=\"#topics-db-multi-db-routing\"><span class=\"std std-ref\">routeur de base de données</span></a> implémentant une politique de restriction de disponibilité de certains modèles.</p>\n<p>Si comme dans le second exemple ci-dessus vous avez laissé vide la base de données <code class=\"docutils literal notranslate\"><span class=\"pre\">default</span></code>, vous devez fournir un nom de base de données chaque fois que vous lancez <a class=\"reference internal\" href=\"/fr/5.0/ref/django-admin/#django-admin-migrate\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">migrate</span></code></a>. Sans cela, une erreur sera produite. Pour le second exemple :</p>\n<div class=\"code-block\" data-language=\"shell\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</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=\"Shell code\"><code>$<span class=\"w\"> </span>./manage.py<span class=\"w\"> </span>migrate<span class=\"w\"> </span>--database<span class=\"o\">=</span>users\n$<span class=\"w\"> </span>./manage.py<span class=\"w\"> </span>migrate<span class=\"w\"> </span>--database<span class=\"o\">=</span>customers\n</code></pre></div>\n<section id=\"using-other-management-commands\">\n<h3>Utilisation d’autres commandes de gestion<a class=\"heading-anchor\" href=\"#using-other-management-commands\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>La plupart des autres commandes <code class=\"docutils literal notranslate\"><span class=\"pre\">django-admin</span></code> interagissant avec la base de données fonctionnent de la même façon que <a class=\"reference internal\" href=\"/fr/5.0/ref/django-admin/#django-admin-migrate\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">migrate</span></code></a>, c’est-à-dire qu’ils n’opèrent toujours que sur une seule base de données à la fois, en se basant sur le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">--database</span></code> pour savoir quelle base de données utiliser.</p>\n<p>Une exception à cette règle est la commande <a class=\"reference internal\" href=\"/fr/5.0/ref/django-admin/#django-admin-makemigrations\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">makemigrations</span></code></a>. Elle valide l’historique des migrations dans la base de données pour détecter d’éventuels problèmes avec les fichiers de migration existants (par exemple suite à une édition manuelle) avant de créer de nouvelles migrations. Par défaut, elle ne contrôle que la base de données <code class=\"docutils literal notranslate\"><span class=\"pre\">default</span></code>, mais elle consulte la méthode <a class=\"reference internal\" href=\"#allow_migrate\" title=\"allow_migrate\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">allow_migrate()</span></code></a> des <a class=\"reference internal\" href=\"#topics-db-multi-db-routing\"><span class=\"std std-ref\">routeurs</span></a> pour autant qu’il y en ait.</p>\n</section>\n</section>\n<section id=\"automatic-database-routing\">\n<span id=\"topics-db-multi-db-routing\"></span><h2>Routage automatique de base de données<a class=\"heading-anchor\" href=\"#automatic-database-routing\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>La façon la plus simple d’utiliser plusieurs bases de données est de définir un plan de routage de base de données. Le plan de routage par défaut garantit que les objets restent « attachés » à leur base de données originale (c’est-à-dire qu’un objet extrait de la base de données <code class=\"docutils literal notranslate\"><span class=\"pre\">foo</span></code> sera également enregistré dans la même base). Le plan de routage par défaut garantit que sans indication particulière de base de données, toutes les requêtes sont dirigées vers la base de données <code class=\"docutils literal notranslate\"><span class=\"pre\">default</span></code>.</p>\n<p>Vous n’avez rien à faire de particulier pour activer le plan de routage par défaut, il est activé d’origine pour tout projet Django. Cependant, si vous avez l’intention d’implémenter un comportement plus élaboré de distribution entre bases de données, vous avez la possibilité de définir et installer vos propres routeurs de base de données.</p>\n<section id=\"database-routers\">\n<h3>Routeurs de base de données<a class=\"heading-anchor\" href=\"#database-routers\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Un routeur de base de données (<code class=\"docutils literal notranslate\"><span class=\"pre\">Router</span></code>) est une classe fournissant jusqu’à quatre méthodes :</p>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"db_for_read\">\n<span class=\"sig-name descname\"><span class=\"pre\">db_for_read</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">model</span></span></em>, <em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">**</span></span><span class=\"n\"><span class=\"pre\">hints</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#db_for_read\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Suggère la base de données à utiliser pour les opérations de lecture pour les objets de type <code class=\"docutils literal notranslate\"><span class=\"pre\">model</span></code>.</p>\n<p>Si une opération de base de données est capable de fournir des informations supplémentaires pouvant aider à choisir la base de données, celles-ci seront contenues dans le dictionnaire <code class=\"docutils literal notranslate\"><span class=\"pre\">hints</span></code>. Vous trouverez <a class=\"reference internal\" href=\"#topics-db-multi-db-hints\"><span class=\"std std-ref\">ci-dessous</span></a> plus de détails au sujet des contenus possibles de <code class=\"docutils literal notranslate\"><span class=\"pre\">hints</span></code>.</p>\n<p>Renvoie <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code> s’il n’y a pas de suggestion.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"db_for_write\">\n<span class=\"sig-name descname\"><span class=\"pre\">db_for_write</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">model</span></span></em>, <em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">**</span></span><span class=\"n\"><span class=\"pre\">hints</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#db_for_write\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Suggère la base de données à utiliser pour les opérations d’écriture pour les objets de type <code class=\"docutils literal notranslate\"><span class=\"pre\">Model</span></code>.</p>\n<p>Si une opération de base de données est capable de fournir des informations supplémentaires pouvant aider à choisir la base de données, celles-ci seront contenues dans le dictionnaire <code class=\"docutils literal notranslate\"><span class=\"pre\">hints</span></code>. Vous trouverez <a class=\"reference internal\" href=\"#topics-db-multi-db-hints\"><span class=\"std std-ref\">ci-dessous</span></a> plus de détails au sujet des contenus possibles de <code class=\"docutils literal notranslate\"><span class=\"pre\">hints</span></code>.</p>\n<p>Renvoie <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code> s’il n’y a pas de suggestion.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"allow_relation\">\n<span class=\"sig-name descname\"><span class=\"pre\">allow_relation</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">obj1</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">obj2</span></span></em>, <em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">**</span></span><span class=\"n\"><span class=\"pre\">hints</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#allow_relation\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Renvoie <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> si une relation entre <code class=\"docutils literal notranslate\"><span class=\"pre\">obj1</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">obj2</span></code> est autorisée, <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code> si la relation est interdite ou <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code> si le routeur n’a pas d’avis. Il s’agit purement d’une opération de validation utilisée par les opérations de clé étrangère et de relations plusieurs-à-plusieurs pour déterminer si une relation entre deux objets doit être permise ou non.</p>\n<p>Si aucun routeur n’a d’opinion (c-à-d. tous les routeurs renvoient <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code>), seules les relations à l’intérieur d’une même base de données sont acceptées.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"allow_migrate\">\n<span class=\"sig-name descname\"><span class=\"pre\">allow_migrate</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">db</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">app_label</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">model_name</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">**</span></span><span class=\"n\"><span class=\"pre\">hints</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#allow_migrate\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Détermine si l’opération de migration est autorisée à s’exécuter pour la base de données ayant l’alias <code class=\"docutils literal notranslate\"><span class=\"pre\">db</span></code>. Renvoie <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> si l’opération doit être appliquée, <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code> si elle ne doit pas l’être ou <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code> si le routeur n’a pas d’avis.</p>\n<p>Le paramètre positionnel <code class=\"docutils literal notranslate\"><span class=\"pre\">app_label</span></code> est l’étiquette de l’application en cours de migration.</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">model_name</span></code> est défini par la plupart des opérations de migration à la valeur de <code class=\"docutils literal notranslate\"><span class=\"pre\">model._meta.model_name</span></code> (la version en minuscules du <code class=\"docutils literal notranslate\"><span class=\"pre\">__name__</span></code> du modèle) du modèle en cours de migration. Sa valeur est <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code> pour les opérations <a class=\"reference internal\" href=\"/fr/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\"><span class=\"pre\">RunPython</span></code></a> et <a class=\"reference internal\" href=\"/fr/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\"><span class=\"pre\">RunSQL</span></code></a> sauf si elles le fournissent par des indications (<code class=\"docutils literal notranslate\"><span class=\"pre\">hints</span></code>).</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">hints</span></code> est utilisé par certaines opérations pour communiquer des informations supplémentaires au routeur.</p>\n<p>Lorsque <code class=\"docutils literal notranslate\"><span class=\"pre\">model_name</span></code> est défini, <code class=\"docutils literal notranslate\"><span class=\"pre\">hints</span></code> contient normalement la classe du modèle dans la clé <code class=\"docutils literal notranslate\"><span class=\"pre\">'model'</span></code>. Notez qu’il peut s’agir d’un <a class=\"reference internal\" href=\"/fr/5.0/topics/migrations/#historical-models\"><span class=\"std std-ref\">modèle historique</span></a>, et de ce fait ne pas comporter d’attributs, méthodes ou gestionnaires personnalisés. Vous ne pouvez compter que sur <code class=\"docutils literal notranslate\"><span class=\"pre\">_meta</span></code>.</p>\n<p>Cette méthode peut aussi être utilisée pour déterminer la disponibilité d’un modèle dans une base de données précise.</p>\n<p><a class=\"reference internal\" href=\"/fr/5.0/ref/django-admin/#django-admin-makemigrations\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">makemigrations</span></code></a> crée toujours des migrations pour les modifications de modèles, mais si <code class=\"docutils literal notranslate\"><span class=\"pre\">allow_migrate()</span></code> renvoie <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code>, toute opération de migration pour <code class=\"docutils literal notranslate\"><span class=\"pre\">model_name</span></code> sera silencieusement ignorée lors de l’exécution de <a class=\"reference internal\" href=\"/fr/5.0/ref/django-admin/#django-admin-migrate\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">migrate</span></code></a> pour <code class=\"docutils literal notranslate\"><span class=\"pre\">db</span></code>. La modification du comportement de <code class=\"docutils literal notranslate\"><span class=\"pre\">allow_migrate()</span></code> pour des modèles qui ont déjà des migrations peut aboutir à des clés étrangères cassées, des tables en trop ou des tables manquantes. Lorsque <a class=\"reference internal\" href=\"/fr/5.0/ref/django-admin/#django-admin-makemigrations\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">makemigrations</span></code></a> vérifie l’historique des migrations, elle ignore les bases de données où aucune application n’autorise les migrations.</p>\n</dd></dl>\n\n<p>Un routeur ne doit pas absolument implémenter <em>toutes</em> ces méthodes, il peut en omettre une ou plusieurs. Si l’une des méthode est absente, Django saute ce routeur lorsqu’il effectue le contrôle correspondant.</p>\n<section id=\"hints\">\n<span id=\"topics-db-multi-db-hints\"></span><h4>Indications (<code class=\"docutils literal notranslate\"><span class=\"pre\">hints</span></code>)<a class=\"heading-anchor\" href=\"#hints\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Les indications reçues par le routeur de base de données dans le dictionnaire <code class=\"docutils literal notranslate\"><span class=\"pre\">hints</span></code> peuvent servir à décider quelle base de données doit recevoir une requête donnée.</p>\n<p>Actuellement, la seule indication fournie est <code class=\"docutils literal notranslate\"><span class=\"pre\">instance</span></code>, une instance d’objet liée à l’opération de lecture ou d’écriture en cours. Il peut s’agir de l’instance en train d’être enregistrée ou d’une instance à ajouter dans une relation plusieurs-à-plusieurs. Dans certains cas, aucune indication d’instance n’est présente. Le routeur vérifie l’existence d’une indication d’instance et détermine lui-même si cette instance doit être utilisée pour modifier le comportement de routage.</p>\n</section>\n</section>\n<section id=\"using-routers\">\n<h3>Utilisation des routeurs<a class=\"heading-anchor\" href=\"#using-routers\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Les routeurs de base de données sont installés par le réglage <a class=\"reference internal\" href=\"/fr/5.0/ref/settings/#std-setting-DATABASE_ROUTERS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">DATABASE_ROUTERS</span></code></a>. Ce réglage définit une liste de noms de classes, chacune définissant un routeur devant être utilisé par le routeur de base (<code class=\"docutils literal notranslate\"><span class=\"pre\">django.db.router</span></code>).</p>\n<p>Le routeur principal est utilisé par les opérations de base de données de Django pour désigner les bases de données à utiliser. Chaque fois qu’une requête a besoin de savoir quelle base de données utiliser, elle appelle le routeur principal, en indiquant un modèle ainsi qu’un indice (si disponible). Le routeur principal essaie chaque classe de routeur tour à tour jusqu’à ce qu’une de ces classes renvoie une suggestion de base de données. Si aucun routeur ne renvoie de suggestion, le routeur principal essaie d’utiliser la propriété <a class=\"reference internal\" href=\"/fr/5.0/ref/models/instances/#django.db.models.Model._state\" title=\"django.db.models.Model._state\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">instance._state.db</span></code></a> de l’instance d’indice. Si aucun indice n’a été indiqué ou si <a class=\"reference internal\" href=\"/fr/5.0/ref/models/instances/#django.db.models.Model._state\" title=\"django.db.models.Model._state\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">instance._state.db</span></code></a> contient <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code>, le routeur principal désigne la base de données <code class=\"docutils literal notranslate\"><span class=\"pre\">default</span></code>.</p>\n</section>\n<section id=\"an-example\">\n<h3>Un exemple<a class=\"heading-anchor\" href=\"#an-example\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<aside class=\"admonition-example-purposes-only admonition\">\n<p class=\"admonition-title\">À titre d’exemple uniquement !</p>\n<p>Cet exemple est prévu pour démontrer la manière dont l’infrastructure de routage peut être utilisée pour modifier l’utilisation des bases de données. Il ignore volontairement certaines questions complexes afin de démontrer comment les routeurs peuvent être utilisés.</p>\n<p>Cet exemple ne fonctionnera pas si l’un des modèles de <code class=\"docutils literal notranslate\"><span class=\"pre\">myapp</span></code> contient des relations vers des modèles stockés ailleurs que dans la base de données <code class=\"docutils literal notranslate\"><span class=\"pre\">other</span></code>. <a class=\"reference internal\" href=\"#no-cross-database-relations\"><span class=\"std std-ref\">Les relations croisées entre base de données</span></a> induisent des problèmes d’intégrité référentielle que Django ne peut actuellement pas gérer.</p>\n<p>La configuration primaire/réplique présentée ici (désignée comme maître/esclave par certaines bases de données) est également biaisée, car elle ne propose aucune solution pour gérer les délais de réplication (c’est-à-dire les incohérences de requêtes dues au temps nécessaire à propager les écritures vers les répliques). Elle ne considère pas non plus l’interaction des transactions avec la stratégie d’utilisation des bases de données.</p>\n</aside>\n<p>Mais qu’est-ce que cela signifie en pratique ? Considérons un autre exemple de configuration. Celle-ci contiendra plusieurs bases de données : une pour l’application <code class=\"docutils literal notranslate\"><span class=\"pre\">auth</span></code> et toutes les autres applications utiliseront une configuration primaire/réplique avec deux répliques en lecture seule. Voici les réglages définissant ces bases de données :</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=\"n\">DATABASES</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n    <span class=\"s2\">&quot;default&quot;</span><span class=\"p\">:</span> <span class=\"p\">{},</span>\n    <span class=\"s2\">&quot;auth_db&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n        <span class=\"s2\">&quot;NAME&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;auth_db_name&quot;</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;ENGINE&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;django.db.backends.mysql&quot;</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;USER&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;mysql_user&quot;</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;PASSWORD&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;swordfish&quot;</span><span class=\"p\">,</span>\n    <span class=\"p\">},</span>\n    <span class=\"s2\">&quot;primary&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n        <span class=\"s2\">&quot;NAME&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;primary_name&quot;</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;ENGINE&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;django.db.backends.mysql&quot;</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;USER&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;mysql_user&quot;</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;PASSWORD&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;spam&quot;</span><span class=\"p\">,</span>\n    <span class=\"p\">},</span>\n    <span class=\"s2\">&quot;replica1&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n        <span class=\"s2\">&quot;NAME&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;replica1_name&quot;</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;ENGINE&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;django.db.backends.mysql&quot;</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;USER&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;mysql_user&quot;</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;PASSWORD&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;eggs&quot;</span><span class=\"p\">,</span>\n    <span class=\"p\">},</span>\n    <span class=\"s2\">&quot;replica2&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n        <span class=\"s2\">&quot;NAME&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;replica2_name&quot;</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;ENGINE&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;django.db.backends.mysql&quot;</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;USER&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;mysql_user&quot;</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;PASSWORD&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;bacon&quot;</span><span class=\"p\">,</span>\n    <span class=\"p\">},</span>\n<span class=\"p\">}</span>\n</code></pre></div>\n<p>Nous devons maintenant gérer le routage. Nous désirons premièrement un routeur sachant envoyer des requêtes pour les applications <code class=\"docutils literal notranslate\"><span class=\"pre\">auth</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">contenttypes</span></code> vers <code class=\"docutils literal notranslate\"><span class=\"pre\">auth_db</span></code> (les modèles <code class=\"docutils literal notranslate\"><span class=\"pre\">auth</span></code> sont liés à <code class=\"docutils literal notranslate\"><span class=\"pre\">ContentType</span></code>, ils doivent donc être stockés dans la même base de données)</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\">AuthRouter</span><span class=\"p\">:</span>\n<span class=\"w\">    </span><span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">    A router to control all database operations on models in the</span>\n<span class=\"sd\">    auth and contenttypes applications.</span>\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n\n    <span class=\"n\">route_app_labels</span> <span class=\"o\">=</span> <span class=\"p\">{</span><span class=\"s2\">&quot;auth&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;contenttypes&quot;</span><span class=\"p\">}</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">db_for_read</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">model</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">hints</span><span class=\"p\">):</span>\n<span class=\"w\">        </span><span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">        Attempts to read auth and contenttypes models go to auth_db.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"k\">if</span> <span class=\"n\">model</span><span class=\"o\">.</span><span class=\"n\">_meta</span><span class=\"o\">.</span><span class=\"n\">app_label</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">route_app_labels</span><span class=\"p\">:</span>\n            <span class=\"k\">return</span> <span class=\"s2\">&quot;auth_db&quot;</span>\n        <span class=\"k\">return</span> <span class=\"kc\">None</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">db_for_write</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">model</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">hints</span><span class=\"p\">):</span>\n<span class=\"w\">        </span><span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">        Attempts to write auth and contenttypes models go to auth_db.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"k\">if</span> <span class=\"n\">model</span><span class=\"o\">.</span><span class=\"n\">_meta</span><span class=\"o\">.</span><span class=\"n\">app_label</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">route_app_labels</span><span class=\"p\">:</span>\n            <span class=\"k\">return</span> <span class=\"s2\">&quot;auth_db&quot;</span>\n        <span class=\"k\">return</span> <span class=\"kc\">None</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">allow_relation</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">obj1</span><span class=\"p\">,</span> <span class=\"n\">obj2</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">hints</span><span class=\"p\">):</span>\n<span class=\"w\">        </span><span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">        Allow relations if a model in the auth or contenttypes apps is</span>\n<span class=\"sd\">        involved.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"k\">if</span> <span class=\"p\">(</span>\n            <span class=\"n\">obj1</span><span class=\"o\">.</span><span class=\"n\">_meta</span><span class=\"o\">.</span><span class=\"n\">app_label</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">route_app_labels</span>\n            <span class=\"ow\">or</span> <span class=\"n\">obj2</span><span class=\"o\">.</span><span class=\"n\">_meta</span><span class=\"o\">.</span><span class=\"n\">app_label</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">route_app_labels</span>\n        <span class=\"p\">):</span>\n            <span class=\"k\">return</span> <span class=\"kc\">True</span>\n        <span class=\"k\">return</span> <span class=\"kc\">None</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=\"w\">        </span><span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">        Make sure the auth and contenttypes apps only appear in the</span>\n<span class=\"sd\">        &#39;auth_db&#39; database.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"k\">if</span> <span class=\"n\">app_label</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">route_app_labels</span><span class=\"p\">:</span>\n            <span class=\"k\">return</span> <span class=\"n\">db</span> <span class=\"o\">==</span> <span class=\"s2\">&quot;auth_db&quot;</span>\n        <span class=\"k\">return</span> <span class=\"kc\">None</span>\n</code></pre></div>\n<p>Et nous voulons également un routeur pour que toutes les autres applications envoient leurs requêtes vers la configuration primaire/réplique, tout en choisissant au hasard une réplique pour la lecture :</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\">random</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">PrimaryReplicaRouter</span><span class=\"p\">:</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">db_for_read</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">model</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">hints</span><span class=\"p\">):</span>\n<span class=\"w\">        </span><span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">        Reads go to a randomly-chosen replica.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"k\">return</span> <span class=\"n\">random</span><span class=\"o\">.</span><span class=\"n\">choice</span><span class=\"p\">([</span><span class=\"s2\">&quot;replica1&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;replica2&quot;</span><span class=\"p\">])</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">db_for_write</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">model</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">hints</span><span class=\"p\">):</span>\n<span class=\"w\">        </span><span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">        Writes always go to primary.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"k\">return</span> <span class=\"s2\">&quot;primary&quot;</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">allow_relation</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">obj1</span><span class=\"p\">,</span> <span class=\"n\">obj2</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">hints</span><span class=\"p\">):</span>\n<span class=\"w\">        </span><span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">        Relations between objects are allowed if both objects are</span>\n<span class=\"sd\">        in the primary/replica pool.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"n\">db_set</span> <span class=\"o\">=</span> <span class=\"p\">{</span><span class=\"s2\">&quot;primary&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;replica1&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;replica2&quot;</span><span class=\"p\">}</span>\n        <span class=\"k\">if</span> <span class=\"n\">obj1</span><span class=\"o\">.</span><span class=\"n\">_state</span><span class=\"o\">.</span><span class=\"n\">db</span> <span class=\"ow\">in</span> <span class=\"n\">db_set</span> <span class=\"ow\">and</span> <span class=\"n\">obj2</span><span class=\"o\">.</span><span class=\"n\">_state</span><span class=\"o\">.</span><span class=\"n\">db</span> <span class=\"ow\">in</span> <span class=\"n\">db_set</span><span class=\"p\">:</span>\n            <span class=\"k\">return</span> <span class=\"kc\">True</span>\n        <span class=\"k\">return</span> <span class=\"kc\">None</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=\"w\">        </span><span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">        All non-auth models end up in this pool.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"k\">return</span> <span class=\"kc\">True</span>\n</code></pre></div>\n<p>Pour terminer, nous ajoutons dans le fichier de réglages le code suivant (remplaçant <code class=\"docutils literal notranslate\"><span class=\"pre\">path.to.</span></code> par le chemin Python réel vers les modules où les routeurs sont définis) :</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=\"n\">DATABASE_ROUTERS</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"s2\">&quot;path.to.AuthRouter&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;path.to.PrimaryReplicaRouter&quot;</span><span class=\"p\">]</span>\n</code></pre></div>\n<p>L’ordre dans lequel les routeurs sont traités a son importance. Les routeurs sont interrogés dans leur ordre d’apparition dans le réglage  <a class=\"reference internal\" href=\"/fr/5.0/ref/settings/#std-setting-DATABASE_ROUTERS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">DATABASE_ROUTERS</span></code></a>. Dans cet exemple, <code class=\"docutils literal notranslate\"><span class=\"pre\">AuthRouter</span></code> est traité avant <code class=\"docutils literal notranslate\"><span class=\"pre\">PrimaryReplicaRouter</span></code>, et par conséquent, les décisions concernant les modèles de <code class=\"docutils literal notranslate\"><span class=\"pre\">auth</span></code> sont prises avant toute autre décision. Si le réglage <a class=\"reference internal\" href=\"/fr/5.0/ref/settings/#std-setting-DATABASE_ROUTERS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">DATABASE_ROUTERS</span></code></a> contenait les deux routeurs dans l’ordre inverse, <code class=\"docutils literal notranslate\"><span class=\"pre\">PrimaryReplicaRouter.allow_migrate()</span></code> serait traité en premier. La nature « ramasse-tout » de l’implémentation de <code class=\"docutils literal notranslate\"><span class=\"pre\">PrimaryReplicaRouter</span></code> signifierait que tous les modèles seraient accessibles dans toutes les bases de données.</p>\n<p>Avec l’installation de cette configuration et toutes les bases de données migrées en accord avec <a class=\"reference internal\" href=\"#synchronizing-multiple-databases\"><span class=\"std std-ref\">Synchronisation des bases de données</span></a>, exécutons un peu de code Django :</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</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 console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"c1\"># This retrieval will be performed on the &#39;auth_db&#39; database</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">fred</span> <span class=\"o\">=</span> <span class=\"n\">User</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"n\">username</span><span class=\"o\">=</span><span class=\"s2\">&quot;fred&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">fred</span><span class=\"o\">.</span><span class=\"n\">first_name</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;Frederick&quot;</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"c1\"># This save will also be directed to &#39;auth_db&#39;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">fred</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">()</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"c1\"># These retrieval will be randomly allocated to a replica database</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">dna</span> <span class=\"o\">=</span> <span class=\"n\">Person</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s2\">&quot;Douglas Adams&quot;</span><span class=\"p\">)</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"c1\"># A new object has no database allocation when created</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">mh</span> <span class=\"o\">=</span> <span class=\"n\">Book</span><span class=\"p\">(</span><span class=\"n\">title</span><span class=\"o\">=</span><span class=\"s2\">&quot;Mostly Harmless&quot;</span><span class=\"p\">)</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"c1\"># This assignment will consult the router, and set mh onto</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"c1\"># the same database as the author object</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">mh</span><span class=\"o\">.</span><span class=\"n\">author</span> <span class=\"o\">=</span> <span class=\"n\">dna</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"c1\"># This save will force the &#39;mh&#39; instance onto the primary database...</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">mh</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">()</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"c1\"># ... but if we re-retrieve the object, it will come back on a replica</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">mh</span> <span class=\"o\">=</span> <span class=\"n\">Book</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"n\">title</span><span class=\"o\">=</span><span class=\"s2\">&quot;Mostly Harmless&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Cet exemple définissait un routeur pour gérer l’interaction avec les modèles de l’application <code class=\"docutils literal notranslate\"><span class=\"pre\">auth</span></code> et d’autres routeurs pour gérer l’interaction avec toutes les autres applications. Si vous avez laissé vide la base de données <code class=\"docutils literal notranslate\"><span class=\"pre\">default</span></code> et que vous ne vouliez pas définir un routeur de base de données « fourre-tout » pour gérer toutes les applications non spécifiées explicitement, les routeurs doivent gérer les noms de toutes les applications dans <a class=\"reference internal\" href=\"/fr/5.0/ref/settings/#std-setting-INSTALLED_APPS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">INSTALLED_APPS</span></code></a> avant d’effectuer la migration. Voir <a class=\"reference internal\" href=\"#contrib-app-multiple-databases\"><span class=\"std std-ref\">Comportement des applications contribuées</span></a> pour plus d’informations sur les applications contribuées qui doivent être ensemble dans la même base de données.</p>\n</section>\n</section>\n<section id=\"manually-selecting-a-database\">\n<h2>Sélection manuelle d’une base de données<a class=\"heading-anchor\" href=\"#manually-selecting-a-database\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Django offre également une API permettant de conserver un contrôle total sur l’utilisation des base de données dans votre code. L’attribution manuelle d’une base de données est prioritaire par rapport à l’attribution provenant d’un routeur.</p>\n<section id=\"manually-selecting-a-database-for-a-queryset\">\n<h3>Sélection manuelle d’une base de données pour un <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code><a class=\"heading-anchor\" href=\"#manually-selecting-a-database-for-a-queryset\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Vous pouvez choisir la base de données d’un <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> à tout moment dans la « chaîne » du <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code>. Appelez <code class=\"docutils literal notranslate\"><span class=\"pre\">using()</span></code> sur le <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> pour obtenir un autre <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> utilisant la base de données indiquée.</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">using()</span></code> accepte un seul paramètre : l’alias de la base de données devant recevoir la requête à exécuter. Par exemple :</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</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 console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"c1\"># This will run on the &#39;default&#39; database.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Author</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">all</span><span class=\"p\">()</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"c1\"># So will this.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Author</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">using</span><span class=\"p\">(</span><span class=\"s2\">&quot;default&quot;</span><span class=\"p\">)</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"c1\"># This will run on the &#39;other&#39; database.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Author</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">using</span><span class=\"p\">(</span><span class=\"s2\">&quot;other&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n</section>\n<section id=\"selecting-a-database-for-save\">\n<h3>Sélection d’une base de données pour <code class=\"docutils literal notranslate\"><span class=\"pre\">save()</span></code><a class=\"heading-anchor\" href=\"#selecting-a-database-for-save\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Utilisez le paramètre nommé <code class=\"docutils literal notranslate\"><span class=\"pre\">using</span></code> de <code class=\"docutils literal notranslate\"><span class=\"pre\">Model.save()</span></code> pour indiquer dans quelle base de données les données doivent être enregistrées.</p>\n<p>Par exemple, pour enregistrer un objet dans la base de données <code class=\"docutils literal notranslate\"><span class=\"pre\">legacy_users</span></code>, il faut écrire ceci :</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</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 console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">my_object</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">(</span><span class=\"n\">using</span><span class=\"o\">=</span><span class=\"s2\">&quot;legacy_users&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Si vous ne renseignez pas <code class=\"docutils literal notranslate\"><span class=\"pre\">using</span></code>, la méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">save()</span></code> enregistre dans la base de données par défaut attribuée par les routeurs.</p>\n<section id=\"moving-an-object-from-one-database-to-another\">\n<h4>Déplacement d’un objet entre bases de données<a class=\"heading-anchor\" href=\"#moving-an-object-from-one-database-to-another\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Si vous avez enregistré une instance dans une base de données, il peut être tentant d’utiliser <code class=\"docutils literal notranslate\"><span class=\"pre\">save(using=...)</span></code> comme astuce pour copier l’instance vers une nouvelle base de données. Cependant, si vous ne prenez pas certaines précautions nécessaires, cela peut amener à des conséquences inattendues.</p>\n<p>Considérez l’exemple suivant :</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</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 console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">p</span> <span class=\"o\">=</span> <span class=\"n\">Person</span><span class=\"p\">(</span><span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s2\">&quot;Fred&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">p</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">(</span><span class=\"n\">using</span><span class=\"o\">=</span><span class=\"s2\">&quot;first&quot;</span><span class=\"p\">)</span>  <span class=\"c1\"># (statement 1)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">p</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">(</span><span class=\"n\">using</span><span class=\"o\">=</span><span class=\"s2\">&quot;second&quot;</span><span class=\"p\">)</span>  <span class=\"c1\"># (statement 2)</span>\n</code></pre></div>\n<p>Dans l’instruction 1, un nouvel objet <code class=\"docutils literal notranslate\"><span class=\"pre\">Person</span></code> est enregistré dans la base de données <code class=\"docutils literal notranslate\"><span class=\"pre\">first</span></code>. À ce moment, <code class=\"docutils literal notranslate\"><span class=\"pre\">p</span></code> n’a pas encore de clé primaire, ce qui fait que Django génère une instruction SQL <code class=\"docutils literal notranslate\"><span class=\"pre\">INSERT</span></code>. La clé primaire est donc créée et Django attribue cette clé primaire à <code class=\"docutils literal notranslate\"><span class=\"pre\">p</span></code>.</p>\n<p>Lorsque l’enregistrement est effectué à l’instruction 2, <code class=\"docutils literal notranslate\"><span class=\"pre\">p</span></code> a déjà reçu une valeur de clé primaire et Django va utiliser cette clé primaire dans la nouvelle base de données. Si cette valeur de clé primaire n’est pas déjà utilisée dans la base de données <code class=\"docutils literal notranslate\"><span class=\"pre\">second</span></code>, vous n’aurez pas de problème, l’objet sera effectivement copié dans la nouvelle base de données.</p>\n<p>Cependant, si la clé primaire de <code class=\"docutils literal notranslate\"><span class=\"pre\">p</span></code> est déjà utilisée dans la base de données <code class=\"docutils literal notranslate\"><span class=\"pre\">second</span></code>, l’objet existant dans la base de données <code class=\"docutils literal notranslate\"><span class=\"pre\">second</span></code> sera écrasé lors de l’enregistrement de <code class=\"docutils literal notranslate\"><span class=\"pre\">p</span></code>.</p>\n<p>Vous pouvez empêcher cela de deux manières. Premièrement, vous pouvez effacer la clé primaire de l’instance. Si un objet n’a pas de clé primaire, Django le traite comme un nouvel objet, évitant ainsi toute perte de données dans la base de données <code class=\"docutils literal notranslate\"><span class=\"pre\">second</span></code>:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</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 console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">p</span> <span class=\"o\">=</span> <span class=\"n\">Person</span><span class=\"p\">(</span><span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s2\">&quot;Fred&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">p</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">(</span><span class=\"n\">using</span><span class=\"o\">=</span><span class=\"s2\">&quot;first&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">p</span><span class=\"o\">.</span><span class=\"n\">pk</span> <span class=\"o\">=</span> <span class=\"kc\">None</span>  <span class=\"c1\"># Clear the primary key.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">p</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">(</span><span class=\"n\">using</span><span class=\"o\">=</span><span class=\"s2\">&quot;second&quot;</span><span class=\"p\">)</span>  <span class=\"c1\"># Write a completely new object.</span>\n</code></pre></div>\n<p>La seconde possibilité est d’utiliser l’option <code class=\"docutils literal notranslate\"><span class=\"pre\">force_insert</span></code> de <code class=\"docutils literal notranslate\"><span class=\"pre\">save()</span></code> pour être certain que Django produise une instruction SQL <code class=\"docutils literal notranslate\"><span class=\"pre\">INSERT</span></code>:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</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 console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">p</span> <span class=\"o\">=</span> <span class=\"n\">Person</span><span class=\"p\">(</span><span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s2\">&quot;Fred&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">p</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">(</span><span class=\"n\">using</span><span class=\"o\">=</span><span class=\"s2\">&quot;first&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">p</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">(</span><span class=\"n\">using</span><span class=\"o\">=</span><span class=\"s2\">&quot;second&quot;</span><span class=\"p\">,</span> <span class=\"n\">force_insert</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Cela garantit que la personne nommée <code class=\"docutils literal notranslate\"><span class=\"pre\">Fred</span></code> possédera la même clé primaire dans les deux bases de données. Si cette clé primaire est déjà utilisée lorsque vous essayez d’enregistrer dans la base de données <code class=\"docutils literal notranslate\"><span class=\"pre\">second</span></code>, une erreur sera générée.</p>\n</section>\n</section>\n<section id=\"selecting-a-database-to-delete-from\">\n<h3>Sélection d’une base de données pour la suppression<a class=\"heading-anchor\" href=\"#selecting-a-database-to-delete-from\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Par défaut, un appel à la suppression d’un objet existant sera exécuté dans la même base de données qui a été utilisée pour extraire l’objet au préalable :</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</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 console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">u</span> <span class=\"o\">=</span> <span class=\"n\">User</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">using</span><span class=\"p\">(</span><span class=\"s2\">&quot;legacy_users&quot;</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"n\">username</span><span class=\"o\">=</span><span class=\"s2\">&quot;fred&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">u</span><span class=\"o\">.</span><span class=\"n\">delete</span><span class=\"p\">()</span>  <span class=\"c1\"># will delete from the `legacy_users` database</span>\n</code></pre></div>\n<p>Pour indiquer la base de données dans laquelle un modèle sera supprimé, transmettez un paramètre nommé <code class=\"docutils literal notranslate\"><span class=\"pre\">using</span></code> à la méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">Model.delete()</span></code>. Ce paramètre joue le même rôle que le même paramètre avec <code class=\"docutils literal notranslate\"><span class=\"pre\">save()</span></code>.</p>\n<p>Par exemple, si vous migrez un utilisateur à partir de la base de données <code class=\"docutils literal notranslate\"><span class=\"pre\">legacy_users</span></code> vers la base de données <code class=\"docutils literal notranslate\"><span class=\"pre\">new_users</span></code>, voici les commandes que vous pourriez utiliser :</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</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 console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">user_obj</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">(</span><span class=\"n\">using</span><span class=\"o\">=</span><span class=\"s2\">&quot;new_users&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">user_obj</span><span class=\"o\">.</span><span class=\"n\">delete</span><span class=\"p\">(</span><span class=\"n\">using</span><span class=\"o\">=</span><span class=\"s2\">&quot;legacy_users&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n</section>\n<section id=\"using-managers-with-multiple-databases\">\n<h3>Utilisation de gestionnaires avec plusieurs bases de données<a class=\"heading-anchor\" href=\"#using-managers-with-multiple-databases\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Utilisez la méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">db_manager()</span></code> des gestionnaires pour donner à ceux-ci accès à une base de données autre que celle par défaut.</p>\n<p>Par exemple, admettons que vous ayez une méthode d’un gestionnaire personnalisé agissant sur la base de données, <code class=\"docutils literal notranslate\"><span class=\"pre\">User.objects.create_user()</span></code>. Comme <code class=\"docutils literal notranslate\"><span class=\"pre\">create_user()</span></code> est une méthode de gestionnaire, et non une méthode de <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code>, il n’est pas possible d’écrire <code class=\"docutils literal notranslate\"><span class=\"pre\">User.objects.using('new_users').create_user()</span></code> (la méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">create_user()</span></code> n’est disponible que sur <code class=\"docutils literal notranslate\"><span class=\"pre\">User.objects</span></code>, le gestionnaire, et non pas sur les objets <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> dérivés du gestionnaire). La solution est d’utiliser <code class=\"docutils literal notranslate\"><span class=\"pre\">db_manager()</span></code>, 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=\"n\">User</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">db_manager</span><span class=\"p\">(</span><span class=\"s2\">&quot;new_users&quot;</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">create_user</span><span class=\"p\">(</span><span class=\"o\">...</span><span class=\"p\">)</span>\n</code></pre></div>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">db_manager()</span></code> renvoie une copie du gestionnaire lié à la base de données que vous indiquez.</p>\n<section id=\"using-get-queryset-with-multiple-databases\">\n<h4>Utilisation de <code class=\"docutils literal notranslate\"><span class=\"pre\">get_queryset()</span></code> avec plusieurs bases de données<a class=\"heading-anchor\" href=\"#using-get-queryset-with-multiple-databases\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Si vous surchargez <code class=\"docutils literal notranslate\"><span class=\"pre\">get_queryset()</span></code> dans votre gestionnaire, prenez soin de soit appeler la méthode du parent (en utilisant <code class=\"docutils literal notranslate\"><span class=\"pre\">super()</span></code>)  ou soit de gérer de manière appropriée l’attribut <code class=\"docutils literal notranslate\"><span class=\"pre\">_db</span></code> du gestionnaire (une chaîne contenant le nom de la base de données à utiliser).</p>\n<p>Par exemple, si vous souhaitiez renvoyer une classe <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> personnalisée à partir de la méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">get_queryset</span></code>, vous pourriez faire 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=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MyManager</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Manager</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get_queryset</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"n\">qs</span> <span class=\"o\">=</span> <span class=\"n\">CustomQuerySet</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">model</span><span class=\"p\">)</span>\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_db</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n            <span class=\"n\">qs</span> <span class=\"o\">=</span> <span class=\"n\">qs</span><span class=\"o\">.</span><span class=\"n\">using</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_db</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"n\">qs</span>\n</code></pre></div>\n</section>\n</section>\n</section>\n<section id=\"exposing-multiple-databases-in-django-s-admin-interface\">\n<h2>Exposition de plusieurs bases de données dans l’interface d’administration<a class=\"heading-anchor\" href=\"#exposing-multiple-databases-in-django-s-admin-interface\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>L’interface d’administration de Django ne contient pas de prise en charge explicite de plusieurs bases de données. Si vous souhaitez mettre à disposition une interface d’administration pour un modèle sur une autre base de données que celle indiquée par votre chaîne de routage, il vous faudra écrire des classes <a class=\"reference internal\" href=\"/fr/5.0/ref/contrib/admin/#django.contrib.admin.ModelAdmin\" title=\"django.contrib.admin.ModelAdmin\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">ModelAdmin</span></code></a> personnalisées qui vont piloter l’administration vers l’utilisation d’une base de données spécifique pour le contenu.</p>\n<p>Les objets <code class=\"docutils literal notranslate\"><span class=\"pre\">ModelAdmin</span></code> possèdent les méthodes suivantes qui nécessitent une adaptation pour la prise en charge de plusieurs bases de données :</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\">MultiDBModelAdmin</span><span class=\"p\">(</span><span class=\"n\">admin</span><span class=\"o\">.</span><span class=\"n\">ModelAdmin</span><span class=\"p\">):</span>\n    <span class=\"c1\"># A handy constant for the name of the alternate database.</span>\n    <span class=\"n\">using</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;other&quot;</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">save_model</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"n\">obj</span><span class=\"p\">,</span> <span class=\"n\">form</span><span class=\"p\">,</span> <span class=\"n\">change</span><span class=\"p\">):</span>\n        <span class=\"c1\"># Tell Django to save objects to the &#39;other&#39; database.</span>\n        <span class=\"n\">obj</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">(</span><span class=\"n\">using</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">using</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">delete_model</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"n\">obj</span><span class=\"p\">):</span>\n        <span class=\"c1\"># Tell Django to delete objects from the &#39;other&#39; database</span>\n        <span class=\"n\">obj</span><span class=\"o\">.</span><span class=\"n\">delete</span><span class=\"p\">(</span><span class=\"n\">using</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">using</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get_queryset</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">request</span><span class=\"p\">):</span>\n        <span class=\"c1\"># Tell Django to look for objects on the &#39;other&#39; database.</span>\n        <span class=\"k\">return</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">get_queryset</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">using</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">using</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">formfield_for_foreignkey</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">db_field</span><span class=\"p\">,</span> <span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n        <span class=\"c1\"># Tell Django to populate ForeignKey widgets using a query</span>\n        <span class=\"c1\"># on the &#39;other&#39; database.</span>\n        <span class=\"k\">return</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">formfield_for_foreignkey</span><span class=\"p\">(</span>\n            <span class=\"n\">db_field</span><span class=\"p\">,</span> <span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"n\">using</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">using</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span>\n        <span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">formfield_for_manytomany</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">db_field</span><span class=\"p\">,</span> <span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n        <span class=\"c1\"># Tell Django to populate ManyToMany widgets using a query</span>\n        <span class=\"c1\"># on the &#39;other&#39; database.</span>\n        <span class=\"k\">return</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">formfield_for_manytomany</span><span class=\"p\">(</span>\n            <span class=\"n\">db_field</span><span class=\"p\">,</span> <span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"n\">using</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">using</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span>\n        <span class=\"p\">)</span>\n</code></pre></div>\n<p>L’exemple présenté ci-dessus implémente une stratégie basée sur plusieurs bases de données où tous les objets d’un type donné sont stockés dans une base de données spécifique (par ex. tous les objets <code class=\"docutils literal notranslate\"><span class=\"pre\">User</span></code> se trouvent dans la base de données <code class=\"docutils literal notranslate\"><span class=\"pre\">other</span></code>). Si votre utilisation de plusieurs bases de données est plus complexe, votre classe <code class=\"docutils literal notranslate\"><span class=\"pre\">ModelAdmin</span></code> devra refléter cette stratégie.</p>\n<p>Les objets <a class=\"reference internal\" href=\"/fr/5.0/ref/contrib/admin/#django.contrib.admin.InlineModelAdmin\" title=\"django.contrib.admin.InlineModelAdmin\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">InlineModelAdmin</span></code></a> peuvent être gérés d’une manière similaire. Ils nécessitent trois méthodes personnalisées :</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\">MultiDBTabularInline</span><span class=\"p\">(</span><span class=\"n\">admin</span><span class=\"o\">.</span><span class=\"n\">TabularInline</span><span class=\"p\">):</span>\n    <span class=\"n\">using</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;other&quot;</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get_queryset</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">request</span><span class=\"p\">):</span>\n        <span class=\"c1\"># Tell Django to look for inline objects on the &#39;other&#39; database.</span>\n        <span class=\"k\">return</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">get_queryset</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">using</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">using</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">formfield_for_foreignkey</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">db_field</span><span class=\"p\">,</span> <span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n        <span class=\"c1\"># Tell Django to populate ForeignKey widgets using a query</span>\n        <span class=\"c1\"># on the &#39;other&#39; database.</span>\n        <span class=\"k\">return</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">formfield_for_foreignkey</span><span class=\"p\">(</span>\n            <span class=\"n\">db_field</span><span class=\"p\">,</span> <span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"n\">using</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">using</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span>\n        <span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">formfield_for_manytomany</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">db_field</span><span class=\"p\">,</span> <span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n        <span class=\"c1\"># Tell Django to populate ManyToMany widgets using a query</span>\n        <span class=\"c1\"># on the &#39;other&#39; database.</span>\n        <span class=\"k\">return</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">formfield_for_manytomany</span><span class=\"p\">(</span>\n            <span class=\"n\">db_field</span><span class=\"p\">,</span> <span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"n\">using</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">using</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span>\n        <span class=\"p\">)</span>\n</code></pre></div>\n<p>Après avoir écrit les définitions des classes d’administration des modèles, celles-ci peuvent être inscrites dans n’importe quelle instance <code class=\"docutils literal notranslate\"><span class=\"pre\">Admin</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.contrib</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">admin</span>\n\n\n<span class=\"c1\"># Specialize the multi-db admin objects for use with specific models.</span>\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">BookInline</span><span class=\"p\">(</span><span class=\"n\">MultiDBTabularInline</span><span class=\"p\">):</span>\n    <span class=\"n\">model</span> <span class=\"o\">=</span> <span class=\"n\">Book</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">PublisherAdmin</span><span class=\"p\">(</span><span class=\"n\">MultiDBModelAdmin</span><span class=\"p\">):</span>\n    <span class=\"n\">inlines</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">BookInline</span><span class=\"p\">]</span>\n\n\n<span class=\"n\">admin</span><span class=\"o\">.</span><span class=\"n\">site</span><span class=\"o\">.</span><span class=\"n\">register</span><span class=\"p\">(</span><span class=\"n\">Author</span><span class=\"p\">,</span> <span class=\"n\">MultiDBModelAdmin</span><span class=\"p\">)</span>\n<span class=\"n\">admin</span><span class=\"o\">.</span><span class=\"n\">site</span><span class=\"o\">.</span><span class=\"n\">register</span><span class=\"p\">(</span><span class=\"n\">Publisher</span><span class=\"p\">,</span> <span class=\"n\">PublisherAdmin</span><span class=\"p\">)</span>\n\n<span class=\"n\">othersite</span> <span class=\"o\">=</span> <span class=\"n\">admin</span><span class=\"o\">.</span><span class=\"n\">AdminSite</span><span class=\"p\">(</span><span class=\"s2\">&quot;othersite&quot;</span><span class=\"p\">)</span>\n<span class=\"n\">othersite</span><span class=\"o\">.</span><span class=\"n\">register</span><span class=\"p\">(</span><span class=\"n\">Publisher</span><span class=\"p\">,</span> <span class=\"n\">MultiDBModelAdmin</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Cet exemple configure deux sites d’administration. Dans le premier site, les objets <code class=\"docutils literal notranslate\"><span class=\"pre\">Author</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">Publisher</span></code> sont exposés ; les objets <code class=\"docutils literal notranslate\"><span class=\"pre\">Publisher</span></code> possèdent un sous-formulaire tabulaire affichant les livres publiés par cet éditeur. Le second site n’expose que les éditeurs, sans sous-formulaire.</p>\n</section>\n<section id=\"using-raw-cursors-with-multiple-databases\">\n<h2>Utilisation directe de curseurs avec plusieurs bases de données<a class=\"heading-anchor\" href=\"#using-raw-cursors-with-multiple-databases\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Si vous utilisez plus d’une base de données, vous pouvez utiliser <code class=\"docutils literal notranslate\"><span class=\"pre\">django.db.connections</span></code> pour obtenir la connexion (et le curseur) d’une base de données spécifique. <code class=\"docutils literal notranslate\"><span class=\"pre\">django.db.connections</span></code> est un objet de type dictionnaire permettant d’obtenir une connexion particulière au moyen de son alias :</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\">connections</span>\n\n<span class=\"k\">with</span> <span class=\"n\">connections</span><span class=\"p\">[</span><span class=\"s2\">&quot;my_db_alias&quot;</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">cursor</span><span class=\"p\">()</span> <span class=\"k\">as</span> <span class=\"n\">cursor</span><span class=\"p\">:</span>\n    <span class=\"o\">...</span>\n</code></pre></div>\n</section>\n<section id=\"limitations-of-multiple-databases\">\n<h2>Limites des bases de données multiples<a class=\"heading-anchor\" href=\"#limitations-of-multiple-databases\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<section id=\"cross-database-relations\">\n<span id=\"no-cross-database-relations\"></span><h3>Relations croisées entre bases de données<a class=\"heading-anchor\" href=\"#cross-database-relations\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Django n’offre actuellement aucune prise en charge des clés étrangères ou des relations plusieurs-à-plusieurs entre différentes bases de données. Si vous avez utilisé un routeur pour distribuer les modèles entre différentes bases de données, toute relation de clé étrangère ou plusieurs-à-plusieurs définie par ces modèles doit être interne à une seule base de données.</p>\n<p>L’intégrité référentielle en est la cause. Afin de maintenir une relation entre deux objets, Django a besoin de savoir que la clé primaire de l’objet lié est valide. Si la clé primaire est stockée dans une autre base de données, il n’est pas possible d’évaluer de manière simple la validité de la clé primaire.</p>\n<p>Si vous utilisez Postgres, SQLite, Oracle ou MySQL avec InnoDB, cette garantie d’intégrité est assurée au niveau de la base de données, les contraintes de clés au niveau de la base de données empêchant la création de relations qui ne peuvent pas être validées.</p>\n<p>Cependant, si vous utilisez MySQL avec des tables MyISAM, il n’y a pas d’intégrité référentielle ; par conséquent, il est possible de créer des clés étrangères « simulées » entre bases de données. Toutefois, cette configuration n’est pas prise en charge officiellement par Django.</p>\n</section>\n<section id=\"behavior-of-contrib-apps\">\n<span id=\"contrib-app-multiple-databases\"></span><h3>Comportement des applications contribuées<a class=\"heading-anchor\" href=\"#behavior-of-contrib-apps\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Plusieurs applications contribuées contiennent des modèles, et certaines applications ont des dépendances. Comme les relations croisées entre bases de données sont impossibles, il en résulte certaines restrictions sur la façon dont ces modèles peuvent être partagés entre différentes bases de données :</p>\n<ul class=\"simple\">\n<li><p>Les modèles <code class=\"docutils literal notranslate\"><span class=\"pre\">contenttypes.ContentType</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">sessions.Session</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">sites.Site</span></code> peuvent être indépendamment stockés dans n’importe quelle base de données, pour autant qu’un routeur adéquat soit utilisé.</p></li>\n<li><p>Les modèles <code class=\"docutils literal notranslate\"><span class=\"pre\">auth</span></code> (<code class=\"docutils literal notranslate\"><span class=\"pre\">User</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">Group</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">Permission</span></code>) sont liés les uns aux autres et à <code class=\"docutils literal notranslate\"><span class=\"pre\">ContentType</span></code>, ils doivent donc être stockés dans la même base de données que <code class=\"docutils literal notranslate\"><span class=\"pre\">ContentType</span></code>.</p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">admin</span></code> dépend de <code class=\"docutils literal notranslate\"><span class=\"pre\">auth</span></code>, donc ses modèles doivent se trouver dans la même base de données que <code class=\"docutils literal notranslate\"><span class=\"pre\">auth</span></code>.</p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">flatpages</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">redirects</span></code> dépendent de <code class=\"docutils literal notranslate\"><span class=\"pre\">sites</span></code>, donc leurs modèles doivent être dans la même base de données que <code class=\"docutils literal notranslate\"><span class=\"pre\">sites</span></code>.</p></li>\n</ul>\n<p>De plus, certains objets sont automatiquement créés juste après que <a class=\"reference internal\" href=\"/fr/5.0/ref/django-admin/#django-admin-migrate\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">migrate</span></code></a> crée la table pour les stocker en base de données :</p>\n<ul class=\"simple\">\n<li><p>un <code class=\"docutils literal notranslate\"><span class=\"pre\">Site</span></code> par défaut,</p></li>\n<li><p>un <code class=\"docutils literal notranslate\"><span class=\"pre\">ContentType</span></code> pour chaque modèle (y compris ceux qui ne sont pas stockés en base de données),</p></li>\n<li><p>les <code class=\"docutils literal notranslate\"><span class=\"pre\">Permission</span></code> pour chaque modèle (y compris ceux qui ne sont pas stockés en base de données).</p></li>\n</ul>\n<p>Pour des configurations courantes avec plusieurs bases de données, il n’est pas utile de disposer de ces objets dans plus d’une base de données. Ces configurations courantes incluent les configurations maître-esclave et la connexion à des bases de données externes. Il est donc recommandé d’écrire un <a class=\"reference internal\" href=\"#topics-db-multi-db-routing\"><span class=\"std std-ref\">routeur de base de données</span></a> autorisant la synchronisation de ces trois modèles vers une seule base de données. Utilisez la même approche pour les autres applications contribuées ou de tierce partie dont les tables n’ont pas besoin de se trouver dans plusieurs bases de données.</p>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">Avertissement</p>\n<p>Si vous synchronisez les types de contenus dans plus d’une base de données, soyez conscient que leur clés primaires peuvent différer d’une base de données à l’autre. Cela peut aboutir à des corruptions ou des pertes de données.</p>\n</aside>\n</section>\n</section>","rootId":"multiple-databases","toc":[{"title":"Définition des bases de données","anchor":"defining-your-databases","children":[]},{"title":"Synchronisation des bases de données","anchor":"synchronizing-your-databases","children":[{"title":"Utilisation d’autres commandes de gestion","anchor":"using-other-management-commands","children":[]}]},{"title":"Routage automatique de base de données","anchor":"automatic-database-routing","children":[{"title":"Routeurs de base de données","anchor":"database-routers","children":[{"title":"Indications (hints)","anchor":"hints","children":[]}]},{"title":"Utilisation des routeurs","anchor":"using-routers","children":[]},{"title":"Un exemple","anchor":"an-example","children":[]}]},{"title":"Sélection manuelle d’une base de données","anchor":"manually-selecting-a-database","children":[{"title":"Sélection manuelle d’une base de données pour un QuerySet","anchor":"manually-selecting-a-database-for-a-queryset","children":[]},{"title":"Sélection d’une base de données pour save()","anchor":"selecting-a-database-for-save","children":[{"title":"Déplacement d’un objet entre bases de données","anchor":"moving-an-object-from-one-database-to-another","children":[]}]},{"title":"Sélection d’une base de données pour la suppression","anchor":"selecting-a-database-to-delete-from","children":[]},{"title":"Utilisation de gestionnaires avec plusieurs bases de données","anchor":"using-managers-with-multiple-databases","children":[{"title":"Utilisation de get_queryset() avec plusieurs bases de données","anchor":"using-get-queryset-with-multiple-databases","children":[]}]}]},{"title":"Exposition de plusieurs bases de données dans l’interface d’administration","anchor":"exposing-multiple-databases-in-django-s-admin-interface","children":[]},{"title":"Utilisation directe de curseurs avec plusieurs bases de données","anchor":"using-raw-cursors-with-multiple-databases","children":[]},{"title":"Limites des bases de données multiples","anchor":"limitations-of-multiple-databases","children":[{"title":"Relations croisées entre bases de données","anchor":"cross-database-relations","children":[]},{"title":"Comportement des applications contribuées","anchor":"behavior-of-contrib-apps","children":[]}]}],"breadcrumbs":[{"docname":"topics/index","title":"Utilisation de Django","url":"/fr/5.0/topics/"},{"docname":"topics/db/index","title":"Modèles et bases de données","url":"/fr/5.0/topics/db/"}],"prev":{"docname":"topics/db/transactions","title":"Transactions de base de données","url":"/fr/5.0/topics/db/transactions/"},"next":{"docname":"topics/db/tablespaces","title":"Espaces de tables","url":"/fr/5.0/topics/db/tablespaces/"},"formats":{"html":"/fr/5.0/topics/db/multi-db/","markdown":"/fr/5.0/topics/db/multi-db.md","json":"/fr/5.0/topics/db/multi-db.json"},"source":"https://github.com/django/django/blob/stable/5.0.x/docs/topics/db/multi-db.txt","official":"https://docs.djangoproject.com/fr/5.0/topics/db/multi-db/","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","it","pt-br","ko","es","el","pl"]}