{"title":"Bases de données","version":"1.11","locale":"fr","docname":"ref/databases","url":"/fr/1.11/ref/databases/","canonical":"https://djangodocs.dev/fr/1.11/ref/databases/","summary":"Django tente d’activer autant de fonctionnalités que possible sur tous les types de base de données.","html":"<h1>Bases de données<a class=\"heading-anchor\" href=\"#databases\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>Django tente d’activer autant de fonctionnalités que possible sur tous les types de base de données. Cependant, tous les types de base de données ne sont pas semblables, et nous avons dû prendre des décisions de conception sur les fonctionnalités à activer et les hypothèses sur lesquelles nous pouvions nous baser en toute sécurité.</p>\n<p>Ce fichier décrit quelques-unes des caractéristiques qui pourraient être pertinentes pour l’utilisation de Django. Bien sûr, il ne remplace pas la documentation ou les manuels de référence spécifiques aux différents serveurs de base de données.</p>\n<section id=\"general-notes\">\n<h2>Remarques générales<a class=\"heading-anchor\" href=\"#general-notes\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<section id=\"persistent-connections\">\n<span id=\"persistent-database-connections\"></span><h3>Connexions persistantes<a class=\"heading-anchor\" href=\"#persistent-connections\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Les connexions persistantes évitent de devoir rétablir une connexion à la base de données pour chaque requête. Elles sont contrôlées par le réglage <a class=\"reference internal\" href=\"/fr/1.11/ref/settings/#std-setting-CONN_MAX_AGE\"><code class=\"xref std std-setting docutils literal notranslate\">CONN_MAX_AGE</code></a> qui définit la durée de vie maximale d’une connexion. Ce réglage peut être défini indépendamment pour chaque base de données.</p>\n<p>La valeur par défaut est <code class=\"docutils literal notranslate\">0</code>, pour préserver le comportement historique de la fermeture de la connexion de base de données à la fin de chaque requête. Pour activer les connexions persistantes, définissez <a class=\"reference internal\" href=\"/fr/1.11/ref/settings/#std-setting-CONN_MAX_AGE\"><code class=\"xref std std-setting docutils literal notranslate\">CONN_MAX_AGE</code></a> à un nombre positif de secondes. Pour que les connexions persistantes soient illimitées dans le temps, définissez-le à <code class=\"docutils literal notranslate\">None</code>.</p>\n<section id=\"connection-management\">\n<h4>Gestion des connexions<a class=\"heading-anchor\" href=\"#connection-management\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Django ouvre une connexion à la base de données lors de la première requête de base de données. Il garde cette connexion ouverte et la réutilise pour les requêtes suivantes. Django ferme la connexion dès que la limite de durée définie par <a class=\"reference internal\" href=\"/fr/1.11/ref/settings/#std-setting-CONN_MAX_AGE\"><code class=\"xref std std-setting docutils literal notranslate\">CONN_MAX_AGE</code></a> est dépassée ou que la connexion n’est plus utilisable.</p>\n<p>Dans le détail, Django ouvre automatiquement une connexion à la base de données chaque fois qu’il en a besoin et qu’il n’en a pas déjà une – soit parce que c’est la première connexion, soit parce que la connexion précédente a été fermée.</p>\n<p>Avant chaque requête à la base de données, Django clôture la connexion si celle-ci a atteint la limite de durée. Si votre base de données termine les connexions inactives après une certaine durée, vous devez définir <a class=\"reference internal\" href=\"/fr/1.11/ref/settings/#std-setting-CONN_MAX_AGE\"><code class=\"xref std std-setting docutils literal notranslate\">CONN_MAX_AGE</code></a> à une valeur inférieure, de sorte que Django ne cherche pas à utiliser une connexion qui a été interrompue par le serveur de base de données (ce problème ne peut affecter que les sites à très faible trafic).</p>\n<p>À la fin de chaque requête à la base de données, Django clôture la connexion si celle-ci a atteint la limite de durée ou si elle est dans un état d’erreur irrécupérable. Si des erreurs de base de données ont eu lieu lors du traitement des requêtes, Django vérifie si la connexion fonctionne encore, et la ferme si ce n’est pas le cas. De cette manière, les erreurs de base de données affectent au plus une requête ; si la connexion devient inutilisable, la prochaine requête obtient une nouvelle connexion.</p>\n</section>\n<section id=\"caveats\">\n<h4>Mises en garde<a class=\"heading-anchor\" href=\"#caveats\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Comme chaque fil d’exécution gère sa propre connexion, la base de données doit prendre en charge au moins autant de connexions simultanées qu’il n’y a de fils d’exécution (threads) de travail pour Django.</p>\n<p>Parfois, la majorité des vues n’accèdent pas à une certaine base de données, par exemple parce que c’est la base de données d’un système externe, ou grâce à la mise en cache. Dans ce cas, vous devez définir <a class=\"reference internal\" href=\"/fr/1.11/ref/settings/#std-setting-CONN_MAX_AGE\"><code class=\"xref std std-setting docutils literal notranslate\">CONN_MAX_AGE</code></a> à une valeur faible, voire à <code class=\"docutils literal notranslate\">0</code>, car cela n’a aucun sens de maintenir une connexion qui est peu susceptible d’être réutilisée. Cela contribuera à garder un petit nombre de connexions simultanées à cette base de données.</p>\n<p>Le serveur de développement crée un nouveau fil d’exécution pour chaque requête qu’il gère, annulant l’effet des connexions persistantes. Ne les activez pas pendant le développement.</p>\n<p>Lorsque Django établit une connexion à la base de données, il met en place les paramètres appropriés en fonction du type de base de données utilisé. Si vous activez les connexions persistantes, cette phase de configuration n’est pas répétée pour chaque requête. Si vous modifiez des paramètres tels que le niveau d’isolement de la connexion ou le fuseau horaire, vous devez soit restaurer les paramètres par défaut de Django à la fin de chaque requête, soit forcer une valeur appropriée avant chaque requête, soit désactiver les connexions persistantes.</p>\n</section>\n</section>\n<section id=\"encoding\">\n<h3>Codage de caractères<a class=\"heading-anchor\" href=\"#encoding\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Django suppose que toutes les bases de données utilisent le codage UTF-8. L’utilisation d’autres codages peut entraîner un comportement inattendu comme des erreurs de base de données « valeur trop longue » pour des données qui sont valides dans Django. Consultez les notes ci-dessous spécifiques à chaque base de données pour obtenir des informations sur la façon de configurer correctement votre base de données.</p>\n</section>\n</section>\n<section id=\"postgresql-notes\">\n<span id=\"id1\"></span><h2>Notes sur PostgreSQL<a class=\"heading-anchor\" href=\"#postgresql-notes\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Django supports PostgreSQL 9.3 and higher. <a class=\"reference external\" href=\"http://initd.org/psycopg/\">psycopg2</a> 2.5.4 through 2.7.7 is\nrequired, though the 2.7.7 is recommended.</p>\n<section id=\"postgresql-connection-settings\">\n<h3>Paramètres de connexion PostgreSQL<a class=\"heading-anchor\" href=\"#postgresql-connection-settings\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Voir <a class=\"reference internal\" href=\"/fr/1.11/ref/settings/#std-setting-HOST\"><code class=\"xref std std-setting docutils literal notranslate\">HOST</code></a> pour plus de détails.</p>\n</section>\n<section id=\"optimizing-postgresql-s-configuration\">\n<h3>Optimisation de la configuration de PostgreSQL<a class=\"heading-anchor\" href=\"#optimizing-postgresql-s-configuration\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Django a besoin des paramètres suivants pour se connecter aux bases de données :</p>\n<ul class=\"simple\">\n<li><p><code class=\"docutils literal notranslate\">client_encoding</code>: <code class=\"docutils literal notranslate\">'UTF8'</code>,</p></li>\n<li><p><code class=\"docutils literal notranslate\">default_transaction_isolation</code>: <code class=\"docutils literal notranslate\">'read committed'</code> par défaut, ou la valeur définie dans les options de connexion (voir ci-dessous),</p></li>\n<li><p><code class=\"docutils literal notranslate\">timezone</code>: <code class=\"docutils literal notranslate\">'UTC'</code> quand <a class=\"reference internal\" href=\"/fr/1.11/ref/settings/#std-setting-USE_TZ\"><code class=\"xref std std-setting docutils literal notranslate\">USE_TZ</code></a> vaut <code class=\"docutils literal notranslate\">True</code>, sinon indiquez la valeur de <a class=\"reference internal\" href=\"/fr/1.11/ref/settings/#std-setting-TIME_ZONE\"><code class=\"xref std std-setting docutils literal notranslate\">TIME_ZONE</code></a>.</p></li>\n</ul>\n<p>Si ces paramètres ont déjà les valeurs correctes, Django n’aura pas à les indiquer pour chaque nouvelle connexion, ce qui améliore légèrement les performances. Vous pouvez les configurer directement dans <code class=\"file docutils literal notranslate\">postgresql.conf</code> ou plus commodément pour chaque utilisateur de base de données avec <a class=\"reference external\" href=\"https://www.postgresql.org/docs/current/static/sql-alterrole.html\">ALTER ROLE</a>.</p>\n<p>Django fonctionne très bien sans cette optimisation, mais chaque nouvelle connexion va faire quelques requêtes supplémentaires pour définir ces paramètres.</p>\n</section>\n<section id=\"isolation-level\">\n<span id=\"database-isolation-level\"></span><h3>Niveau d’isolement<a class=\"heading-anchor\" href=\"#isolation-level\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Comme pour PostgreSQL lui-même, le <a href=\"#id16\"><span class=\"problematic\" id=\"id17\">`niveau d'isolement`_</span></a> de Django vaut par défaut <code class=\"docutils literal notranslate\">READ COMMITTED</code>. Si vous avez besoin d’un plus haut niveau d’isolement tel que <code class=\"docutils literal notranslate\">REPEATABLE READ</code> ou <code class=\"docutils literal notranslate\">SERIALIZABLE</code>, définissez-le dans la partie <a class=\"reference internal\" href=\"/fr/1.11/ref/settings/#std-setting-OPTIONS\"><code class=\"xref std std-setting docutils literal notranslate\">OPTIONS</code></a> de la configuration de base de données <a class=\"reference internal\" href=\"/fr/1.11/ref/settings/#std-setting-DATABASES\"><code class=\"xref std std-setting docutils literal notranslate\">DATABASES</code></a>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">import</span> <span class=\"nn\">psycopg2.extensions</span>\n\nDATABASES <span class=\"o\">=</span> <span class=\"p\">{</span>\n    <span class=\"c1\"># ...</span>\n    <span class=\"s1\">&#39;OPTIONS&#39;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n        <span class=\"s1\">&#39;isolation_level&#39;</span><span class=\"p\">:</span> psycopg2<span class=\"o\">.</span>extensions<span class=\"o\">.</span>ISOLATION_LEVEL_SERIALIZABLE<span class=\"p\">,</span>\n    <span class=\"p\">},</span>\n<span class=\"p\">}</span>\n</code></pre></div>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>Sous des niveaux d’isolement plus élevés, votre application doit être préparée à gérer des exceptions générées lors d’échecs de sérialisation. Cette option est prévue pour des utilisateurs avancés.</p>\n</aside>\n</section>\n<section id=\"indexes-for-varchar-and-text-columns\">\n<h3>Index pour les colonnes <code class=\"docutils literal notranslate\">varchar</code> et <code class=\"docutils literal notranslate\">text</code><a class=\"heading-anchor\" href=\"#indexes-for-varchar-and-text-columns\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Lorsque vous indiquez  <code class=\"docutils literal notranslate\">db_index=True</code> sur vos champs de modèle, Django génère généralement un seul <code class=\"docutils literal notranslate\">CREATE INDEX</code>. Toutefois, si le type de champ de base de données est <code class=\"docutils literal notranslate\">varchar</code> ou <code class=\"docutils literal notranslate\">text</code> (par exemple, pour les champs de type <code class=\"docutils literal notranslate\">CharField</code>, <code class=\"docutils literal notranslate\">FileField</code> ou <code class=\"docutils literal notranslate\">TextField</code>), Django crée alors un index supplémentaire qui utilise une <a class=\"reference external\" href=\"https://www.postgresql.org/docs/current/static/indexes-opclass.html\">classe opérateur de PostgreSQL</a> appropriée pour la colonne. Cet index supplémentaire est nécessaire pour le bon fonctionnement des recherches qui utilisent l’opérateur SQL <code class=\"docutils literal notranslate\">LIKE</code>, comme le font les recherches avec <code class=\"docutils literal notranslate\">contains</code> et <code class=\"docutils literal notranslate\">startswith</code>.</p>\n</section>\n<section id=\"migration-operation-for-adding-extensions\">\n<h3>Opération de migration pour ajouter des extensions<a class=\"heading-anchor\" href=\"#migration-operation-for-adding-extensions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Si vous avez besoin d’ajouter une extension PostgreSQL (comme <code class=\"docutils literal notranslate\">hstore</code>, <code class=\"docutils literal notranslate\">postgis</code>, etc.) en utilisant une migration, utilisez l’opération <a class=\"reference internal\" href=\"/fr/1.11/ref/contrib/postgres/operations/#django.contrib.postgres.operations.CreateExtension\" title=\"django.contrib.postgres.operations.CreateExtension\"><code class=\"xref py py-class docutils literal notranslate\">CreateExtension</code></a>.</p>\n</section>\n<section id=\"server-side-cursors\">\n<span id=\"postgresql-server-side-cursors\"></span><h3>Curseurs côté serveur<a class=\"heading-anchor\" href=\"#server-side-cursors\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<aside class=\"version-note version-added\" data-version=\"1.11\" role=\"note\">\n<p class=\"version-note-title\">New in Django 1.11</p></aside>\n<p>Lorsqu’on utilise <a class=\"reference internal\" href=\"/fr/1.11/ref/models/querysets/#django.db.models.query.QuerySet.iterator\" title=\"django.db.models.query.QuerySet.iterator\"><code class=\"xref py py-meth docutils literal notranslate\">QuerySet.iterator()</code></a>, Django ouvre un <a class=\"reference external\" href=\"https://www.psycopg.org/docs/usage.html#server-side-cursors\" title=\"(disponible dans Psycopg v2.9)\"><span class=\"xref std std-ref\">curseur côté serveur</span></a>. Par défaut, PostgreSQL suppose que seuls les premiers 10% des résultats des requêtes de curseur seront récupérées. Le planificateur de requête passe moins de temps à planifier la requête et commence à renvoyer des résultats plus rapidement, mais cela peut aussi diminuer les performances si plus de 10% des résultats sont récupérés. Les suppositions de PostgreSQL sur le nombre de lignes récupérées d’une requête de curseur sont contrôlées par l’option <a class=\"reference external\" href=\"https://www.postgresql.org/docs/current/static/runtime-config-query.html#GUC-CURSOR-TUPLE-FRACTION\">cursor_tuple_fraction</a>.</p>\n<section id=\"transaction-pooling-and-server-side-cursors\">\n<span id=\"transaction-pooling-server-side-cursors\"></span><h4>Transactions groupées et curseurs côté serveur<a class=\"heading-anchor\" href=\"#transaction-pooling-and-server-side-cursors\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<aside class=\"version-note version-added\" data-version=\"1.11.1\" role=\"note\">\n<p class=\"version-note-title\">New in Django 1.11.1</p></aside>\n<p>L’utilisation d’un concentrateur (pooler) de connexion en mode groupement de transactions (par ex. <a class=\"reference external\" href=\"https://pgbouncer.github.io/\">pgBouncer</a>) nécessite de désactiver les curseurs côté serveur pour cette connexion.</p>\n<p>Les curseurs côté serveur sont propres à une connexion et restent ouverts à la fin d’une transaction lorsque <a class=\"reference internal\" href=\"/fr/1.11/ref/settings/#std-setting-DATABASE-AUTOCOMMIT\"><code class=\"xref std std-setting docutils literal notranslate\">AUTOCOMMIT</code></a> vaut <code class=\"docutils literal notranslate\">True</code>. Une prochaine transaction peut demander l’obtention de davantage de résultats de la part du curseur côté serveur. En mode groupement de transactions, il n’y a aucune garantie que les transactions suivantes réutilisent la même connexion. Si une autre connexion est utilisée, une erreur survient lorsque la transaction fait référence au curseur côté serveur, car ces types de curseurs ne sont accessibles que pour la connexion dans laquelle ils ont été créés.</p>\n<p>Une solution est de désactiver les curseurs côté serveur pour une connexion dans <a class=\"reference internal\" href=\"/fr/1.11/ref/settings/#std-setting-DATABASES\"><code class=\"xref std std-setting docutils literal notranslate\">DATABASES</code></a> en définissant <a class=\"reference internal\" href=\"/fr/1.11/ref/settings/#std-setting-DATABASE-DISABLE_SERVER_SIDE_CURSORS\"><code class=\"xref std std-setting docutils literal notranslate\">DISABLE_SERVER_SIDE_CURSORS</code></a> à <code class=\"docutils literal notranslate\">True</code>.</p>\n<p>Pour bénéficier des curseurs côté serveur en mode de groupement des transactions, il est possible de définir une <a class=\"reference internal\" href=\"/fr/1.11/topics/db/multi-db/\"><span class=\"doc\">autre connexion à la base de données</span></a> afin d’effectuer des requêtes utilisant les curseurs côté serveur. Cette connexion doit se faire soit directement à la base de données soit vers un concentrateur de connexions en mode de groupement par session.</p>\n<p>Une autre option est d’envelopper chaque <code class=\"docutils literal notranslate\">QuerySet</code> utilisant des curseurs côté serveur dans un bloc <a class=\"reference internal\" href=\"/fr/1.11/topics/db/transactions/#django.db.transaction.atomic\" title=\"django.db.transaction.atomic\"><code class=\"xref py py-func docutils literal notranslate\">atomic()</code></a>, car ceci désactive le mode <code class=\"docutils literal notranslate\">autocommit</code> pour la durée de la transaction. De cette façon, le curseur côté serveur ne sera actif que pour la durée de la transaction.</p>\n</section>\n</section>\n<section id=\"manually-specifying-values-of-auto-incrementing-primary-keys\">\n<span id=\"manually-specified-autoincrement-pk\"></span><h3>Indication manuelle des valeurs de clé primaire avec autoincrémentation<a class=\"heading-anchor\" href=\"#manually-specifying-values-of-auto-incrementing-primary-keys\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Django utilise le <a class=\"reference external\" href=\"https://www.postgresql.org/docs/current/static/datatype-numeric.html#DATATYPE-SERIAL\">type de données SERIAL</a> de PostgreSQL pour stocker les clés primaires autoincrémentées. Une colonne <code class=\"docutils literal notranslate\">SERIAL</code> est remplie par des valeurs d’une <a class=\"reference external\" href=\"https://www.postgresql.org/docs/current/static/sql-createsequence.html\">séquence</a> qui garde la trace de la prochaine valeur disponible. L’attribution manuelle d’une valeur à un champ autoincrémenté ne met pas à jour la séquence du champ, ce qui peut causer un conflit plus tard. Par exemple</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=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span> <span class=\"nn\">django.contrib.auth.models</span> <span class=\"kn\">import</span> User\n<span class=\"gp\">&gt;&gt;&gt; </span>User<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>username<span class=\"o\">=</span><span class=\"s1\">&#39;alice&#39;</span><span class=\"p\">,</span> pk<span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"go\">&lt;User: alice&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"c1\"># The sequence hasn&#39;t been updated; its next value is 1.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>User<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>username<span class=\"o\">=</span><span class=\"s1\">&#39;bob&#39;</span><span class=\"p\">)</span>\n<span class=\"gp\">...</span>\n<span class=\"go\">IntegrityError: duplicate key value violates unique constraint</span>\n<span class=\"go\">&quot;auth_user_pkey&quot; DETAIL:  Key (id)=(1) already exists.</span>\n</code></pre></div>\n<p>Si vous devez indiquer de telles valeurs, réinitialisez ensuite la séquence pour éviter de réutiliser une valeur qui se trouve déjà dans la table. La commande d’administration <a class=\"reference internal\" href=\"/fr/1.11/ref/django-admin/#django-admin-sqlsequencereset\"><code class=\"xref std std-djadmin docutils literal notranslate\">sqlsequencereset</code></a> génère les commandes SQL qui font cela.</p>\n</section>\n<section id=\"test-database-templates\">\n<h3>Modèles de base de données de test<a class=\"heading-anchor\" href=\"#test-database-templates\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<aside class=\"version-note version-added\" data-version=\"1.11\" role=\"note\">\n<p class=\"version-note-title\">New in Django 1.11</p></aside>\n<p>On peut utiliser le réglage <a class=\"reference internal\" href=\"/fr/1.11/ref/settings/#std-setting-TEST_TEMPLATE\"><code class=\"xref std std-setting docutils literal notranslate\">TEST['TEMPLATE']</code></a> pour indiquer un <a class=\"reference external\" href=\"https://www.postgresql.org/docs/current/static/sql-createdatabase.html\">modèle</a> (par ex. <code class=\"docutils literal notranslate\">'template0'</code>) à partir duquel la base de données de test est créée.</p>\n</section>\n<section id=\"speeding-up-test-execution-with-non-durable-settings\">\n<h3>Accélération de l’exécution des tests par des réglages temporaires<a class=\"heading-anchor\" href=\"#speeding-up-test-execution-with-non-durable-settings\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Vous pouvez accélérer l’exécution des tests en <a class=\"reference external\" href=\"http://docs.postgresql.fr/9.5/non-durability.html\">configurant PostgreSQL avec perte acceptée</a>.</p>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">Avertissement</p>\n<p>C’est dangereux : votre base de données sera plus sujette aux pertes de données ou aux corruptions dans le case de plantage de serveur ou de coupure de courant. N’utilisez cela que sur des machines de développement où vous pouvez facilement restaurer l’ensemble de toutes les bases de données dans la grappe (cluster).</p>\n</aside>\n</section>\n</section>\n<section id=\"mysql-notes\">\n<span id=\"id3\"></span><h2>Notes sur MySQL<a class=\"heading-anchor\" href=\"#mysql-notes\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<section id=\"version-support\">\n<h3>Versions prises en charge<a class=\"heading-anchor\" href=\"#version-support\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Django supports MySQL 5.5.x - 5.7.x. MySQL 8 and later aren’t supported.</p>\n<p>La fonctionnalité <code class=\"docutils literal notranslate\">inspectdb</code> de Django utilise la base de données <code class=\"docutils literal notranslate\">information_schema</code>, qui contient des données détaillées sur tous les schémas de la base de données.</p>\n<p>Django s’attend à ce que la base de données accepte l’Unicode (codage UTF-8) et lui délègue la charge de faire respecter les transactions et l’intégrité référentielle. Il est important d’être conscient du fait que ces deux derniers aspects ne sont pas réellement appliqués par MySQL lorsque le moteur de stockage MyISAM est utilisé, voir la section suivante.</p>\n</section>\n<section id=\"storage-engines\">\n<span id=\"mysql-storage-engines\"></span><h3>Les moteurs de stockage<a class=\"heading-anchor\" href=\"#storage-engines\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>MySQL possède plusieurs <a class=\"reference external\" href=\"https://dev.mysql.com/doc/refman/en/storage-engines.html\">moteurs de stockage</a>. Vous pouvez changer le moteur de stockage par défaut dans la configuration du serveur.</p>\n<p>Jusqu’à MySQL 5.5.4, le moteur par défaut était <a class=\"reference external\" href=\"https://dev.mysql.com/doc/refman/en/myisam-storage-engine.html\">MyISAM</a> <a class=\"footnote-reference brackets\" href=\"#id6\" id=\"id4\" role=\"doc-noteref\"><span class=\"fn-bracket\">[</span>1<span class=\"fn-bracket\">]</span></a>. Le principal défaut de MyISAM est qu’il ne prend pas en charge les transactions ni le contrôle des contraintes de clé étrangère. Son aspect positif est qu’il était le seul moteur prenant en charge l’indexation et la recherche plein texte jusqu’à MySQL 5.6.4.</p>\n<p>Depuis MySQL 5.5.5, le moteur de stockage par défaut est <a class=\"reference external\" href=\"https://dev.mysql.com/doc/refman/en/innodb-storage-engine.html\">InnoDB</a>. Ce moteur est pleinement transactionnel et prend en charge les références de clé étrangère. Il s’agit probablement du meilleur choix en ce moment. Notez cependant que le compteur d’incrémentation automatique de InnoDB est perdu au redémarrage de MySQL car il ne conserve pas la valeur <code class=\"docutils literal notranslate\">AUTO_INCREMENT</code> mais la recalcule comme « max(id)+1 ». Cela peut aboutir à une réutilisation inappropriée de valeurs <a class=\"reference internal\" href=\"/fr/1.11/ref/models/fields/#django.db.models.AutoField\" title=\"django.db.models.AutoField\"><code class=\"xref py py-class docutils literal notranslate\">AutoField</code></a>.</p>\n<p>Si vous mettez à jour un projet existant à MySQL 5.5.5 et que vous y ajoutez de nouvelles tables, vérifiez que toutes les tables utilisent le même moteur de stockage (MyISAM ou InnoDB). En particulier, si des tables impliquées dans une relation de clé étrangère utilisent des moteurs différents, il peut se produire des erreurs comme celle-ci lors de l’exécution de <code class=\"docutils literal notranslate\">migrate</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>_mysql_exceptions<span class=\"o\">.</span>OperationalError<span class=\"p\">:</span> <span class=\"p\">(</span>\n    <span class=\"mi\">1005</span><span class=\"p\">,</span> <span class=\"s2\">&quot;Can&#39;t create table &#39;</span><span class=\"se\">\\\\</span><span class=\"s2\">db_name</span><span class=\"se\">\\\\</span><span class=\"s2\">.#sql-4a8_ab&#39; (errno: 150)&quot;</span>\n<span class=\"p\">)</span>\n</code></pre></div>\n<aside class=\"footnote-list brackets\">\n<aside class=\"footnote brackets\" id=\"id6\" role=\"doc-footnote\">\n<span class=\"label\"><span class=\"fn-bracket\">[</span><a role=\"doc-backlink\" href=\"#id4\">1</a><span class=\"fn-bracket\">]</span></span>\n<p>À moins que cela n’ait été modifié par le gestionnaire de votre paquet MySQL. Il nous a été rapporté que le programme d’installation de Windows Community Server définit InnoDB comme moteur de stockage par défaut, par exemple.</p>\n</aside>\n</aside>\n</section>\n<section id=\"mysql-db-api-drivers\">\n<span id=\"id7\"></span><h3>Pilotes DB API MySQL<a class=\"heading-anchor\" href=\"#mysql-db-api-drivers\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>L’API de base de données Python est décrite dans la <span class=\"target\" id=\"index-2\"></span><a class=\"pep reference external\" href=\"https://peps.python.org/pep-0249/\"><strong>PEP 249</strong></a>. Il y a trois principaux pilotes MySQL implémentant cette API :</p>\n<ul class=\"simple\">\n<li><p><a class=\"reference external\" href=\"https://pypi.python.org/pypi/MySQL-python/1.2.4\">MySQLdb</a> est un pilote natif qui a été développé et maintenu depuis plus de 10 ans par Andy Dustman.</p></li>\n<li><p><a class=\"reference external\" href=\"https://pypi.python.org/pypi/mysqlclient\">mysqlclient</a> est un dérivé de <code class=\"docutils literal notranslate\">MySQLdb</code> qui ajoute la prise en charge de Python 3 et qui peut être utilisé comme remplacement à l’identique de MySQLdb. Au moment d’écrire ces lignes, il s’agit du <strong>choix recommandé</strong> pour utiliser MySQL avec Django.</p></li>\n<li><p><a class=\"reference external\" href=\"https://dev.mysql.com/downloads/connector/python\">MySQL Connector/Python</a> est un pilote en Python pur écrit par Oracle qui n’a pas besoin de la bibliothèque client MySQL ni d’autres modules Python en dehors de la bibliothèque standard.</p></li>\n</ul>\n<p>Tous ces pilotes respectent la concurrence entre fils d’exécution (thread-safe) et gèrent le regroupement de connexions. <code class=\"docutils literal notranslate\">MySQLdb</code> est le seul qui ne prend pas encore en charge Python 3.</p>\n<p>En plus d’un pilote DB API, Django a besoin d’un adaptateur pour accéder aux pilotes de bases de données à partir de son ORM. Django fournit un adaptateur pour MySQLdb/mysqlclient alors que MySQL Connector/Python inclut le <a class=\"reference external\" href=\"https://dev.mysql.com/doc/connector-python/en/connector-python-django-backend.html\">sien</a>.</p>\n<section id=\"id8\">\n<h4>MySQLdb<a class=\"heading-anchor\" href=\"#id8\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Django a besoin de la version 1.2.3 ou ultérieure de MySQLdb.</p>\n<p>Au moment d’écrire ces lignes, la version la plus récente de MySQLdb (1.2.5) ne prend pas en charge Python 3. Afin de pouvoir utiliser MySQLdb avec Python 3, il est nécessaire de le remplacer par l’installation de <code class=\"docutils literal notranslate\">mysqlclient</code>.</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>Il existe des problèmes connus avec la façon dont MySQLdb convertit les chaînes de date en objets <code class=\"docutils literal notranslate\">datetime</code>. Plus particulièrement, les chaînes de date contenant la valeur <code class=\"docutils literal notranslate\">0000-00-00</code> sont valables pour MySQL mais sont converties en valeur <code class=\"docutils literal notranslate\">None</code> par MySQLdb.</p>\n<p>Cela signifie que vous devez être prudent lors de l’utilisation de <a class=\"reference internal\" href=\"/fr/1.11/ref/django-admin/#django-admin-loaddata\"><code class=\"xref std std-djadmin docutils literal notranslate\">loaddata</code></a> et <a class=\"reference internal\" href=\"/fr/1.11/ref/django-admin/#django-admin-dumpdata\"><code class=\"xref std std-djadmin docutils literal notranslate\">dumpdata</code></a>  avec des lignes qui pourraient contenir des valeurs <code class=\"docutils literal notranslate\">0000-00-00</code>, car elles seront converties en <code class=\"docutils literal notranslate\">None</code>.</p>\n</aside>\n</section>\n<section id=\"id9\">\n<h4>mysqlclient<a class=\"heading-anchor\" href=\"#id9\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Django supports <a class=\"reference external\" href=\"https://pypi.python.org/pypi/mysqlclient\">mysqlclient</a> 1.3.3 through 1.3.13.</p>\n</section>\n<section id=\"id10\">\n<h4>MySQL Connector/Python<a class=\"heading-anchor\" href=\"#id10\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>MySQL Connector/Python est disponible sur cette <a class=\"reference external\" href=\"https://dev.mysql.com/downloads/connector/python/\">page de téléchargement</a>. L’adaptateur Django est disponible dans les versions 1.1.X et ultérieures. Il est possible qu’il ne prenne pas en charge la toute dernière version de Django.</p>\n</section>\n</section>\n<section id=\"time-zone-definitions\">\n<span id=\"mysql-time-zone-definitions\"></span><h3>Définitions de fuseaux horaires<a class=\"heading-anchor\" href=\"#time-zone-definitions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Si vous prévoyez d’utiliser la <a class=\"reference internal\" href=\"/fr/1.11/topics/i18n/timezones/\"><span class=\"doc\">prise en charge des fuseaux horaires</span></a> de Django, utilisez <a class=\"reference external\" href=\"https://dev.mysql.com/doc/refman/en/mysql-tzinfo-to-sql.html\">mysql_tzinfo_to_sql</a> pour charger les tableaux de fuseaux horaires dans la base de données MySQL. Cela doit être fait une seule fois par serveur MySQL, pas pour chaque base de données.</p>\n</section>\n<section id=\"creating-your-database\">\n<h3>Création d’une base de données<a class=\"heading-anchor\" href=\"#creating-your-database\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Vous pouvez <a class=\"reference external\" href=\"https://dev.mysql.com/doc/refman/en/create-database.html\">créer une base de données</a> à l’aide des outils de ligne de commande et de cette commande SQL :</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>CREATE DATABASE <span class=\"o\">&lt;</span>dbname<span class=\"o\">&gt;</span> CHARACTER SET utf8<span class=\"p\">;</span>\n</code></pre></div>\n<p>Cela garantit que toutes les tables et colonnes utilisent le codage UTF-8 par défaut.</p>\n<section id=\"collation-settings\">\n<span id=\"mysql-collation\"></span><h4>Paramètres de tri<a class=\"heading-anchor\" href=\"#collation-settings\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>La méthode de tri (« collation ») d’une colonne détermine l’ordre dans lequel les données sont triées ainsi que les comparaisons d’égalité entre les chaînes. Ce paramètre peut être défini à l’échelle de la base de données mais aussi par table et par colonne. Ceci est <a class=\"reference external\" href=\"https://dev.mysql.com/doc/refman/en/charset.html\">documenté complètement</a> dans la documentation MySQL. Dans tous les cas, la méthode de tri est définie en modifiant directement les tables de la base de données ; Django ne fournit aucun moyen de faire cela au niveau de la définition du modèle.</p>\n<p>Par défaut, avec une base de données UTF-8, MySQL utilise la collation <code class=\"docutils literal notranslate\">utf8_general_ci</code>. En conséquence, toutes les comparaisons d’égalité de chaînes se fait de manière insensible à la casse. C’est-à-dire que « Fred » et « freD » sont jugés équivalents pour la base de données. Si vous avez placé une contrainte unique sur un champ, il ne serait pas permis d’insérer à la fois « aa » et « AA » dans cette même colonne, dans la mesure où leur comparaison dit qu’elles sont identiques (et donc pas uniques) avec la collation par défaut. Si vous souhaitez effectuer des comparaisons sensibles à la casse sur une colonne ou table particulière, modifiez la collation de la colonne ou table en <code class=\"docutils literal notranslate\">utf8_bin</code>.</p>\n<p>Notez que selon les <a class=\"reference external\" href=\"https://dev.mysql.com/doc/refman/en/charset-unicode-sets.html\">Jeux de caractères Unicode MySQL</a>, les comparaisons avec la collation <code class=\"docutils literal notranslate\">utf8_general_ci</code> sont plus rapides, mais légèrement moins correctes que les comparaisons avec <code class=\"docutils literal notranslate\">utf8_unicode_ci</code>. Si cela est acceptable pour votre application, il est préférable d’utiliser <code class=\"docutils literal notranslate\">utf8_general_ci</code> car elle est plus rapide. Dans le cas contraire (par exemple si vous avez besoin de l’ordre du dictionnaire allemand), utilisez <code class=\"docutils literal notranslate\">utf8_unicode_ci</code> car cette collation est plus juste.</p>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">Avertissement</p>\n<p>Les sous-formulaires de modèles valident les champs uniques de manière sensible à la casse. Ainsi, lors de l’utilisation d’une collation de base de données insensible à la casse, des sous-formulaires contenant des valeurs de champs uniques qui ne diffèrent que par leur casse vont passer la validation avec succès, mais au moment de l’enregistrement par <code class=\"docutils literal notranslate\">save()</code>, une exception <code class=\"docutils literal notranslate\">IntegrityError</code> va se produire.</p>\n</aside>\n</section>\n</section>\n<section id=\"connecting-to-the-database\">\n<h3>Connexion à la base de données<a class=\"heading-anchor\" href=\"#connecting-to-the-database\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Reportez-vous à la <a class=\"reference internal\" href=\"/fr/1.11/ref/settings/\"><span class=\"doc\">documentation des réglages</span></a>.</p>\n<p>Les paramètres de connexion sont utilisés dans cet ordre :</p>\n<ol class=\"arabic simple\">\n<li><p><a class=\"reference internal\" href=\"/fr/1.11/ref/settings/#std-setting-OPTIONS\"><code class=\"xref std std-setting docutils literal notranslate\">OPTIONS</code></a>.</p></li>\n<li><p><a class=\"reference internal\" href=\"/fr/1.11/ref/settings/#std-setting-NAME\"><code class=\"xref std std-setting docutils literal notranslate\">NAME</code></a>, <a class=\"reference internal\" href=\"/fr/1.11/ref/settings/#std-setting-USER\"><code class=\"xref std std-setting docutils literal notranslate\">USER</code></a>, <a class=\"reference internal\" href=\"/fr/1.11/ref/settings/#std-setting-PASSWORD\"><code class=\"xref std std-setting docutils literal notranslate\">PASSWORD</code></a>,\n<a class=\"reference internal\" href=\"/fr/1.11/ref/settings/#std-setting-HOST\"><code class=\"xref std std-setting docutils literal notranslate\">HOST</code></a>, <a class=\"reference internal\" href=\"/fr/1.11/ref/settings/#std-setting-PORT\"><code class=\"xref std std-setting docutils literal notranslate\">PORT</code></a></p></li>\n<li><p>Fichiers d’options de MySQL.</p></li>\n</ol>\n<p>En d’autres termes, si vous définissez le nom de la base de données dans <a class=\"reference internal\" href=\"/fr/1.11/ref/settings/#std-setting-OPTIONS\"><code class=\"xref std std-setting docutils literal notranslate\">OPTIONS</code></a>, cette définition a la priorité sur <a class=\"reference internal\" href=\"/fr/1.11/ref/settings/#std-setting-NAME\"><code class=\"xref std std-setting docutils literal notranslate\">NAME</code></a>, qui aurait lui-même la priorité sur n’importe quelle valeur d’un <a class=\"reference external\" href=\"https://dev.mysql.com/doc/refman/en/option-files.html\">fichier d’options MySQL</a>.</p>\n<p>Voici un exemple de configuration qui utilise un fichier d’options MySQL :</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=\"c1\"># settings.py</span>\nDATABASES <span class=\"o\">=</span> <span class=\"p\">{</span>\n    <span class=\"s1\">&#39;default&#39;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n        <span class=\"s1\">&#39;ENGINE&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;django.db.backends.mysql&#39;</span><span class=\"p\">,</span>\n        <span class=\"s1\">&#39;OPTIONS&#39;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n            <span class=\"s1\">&#39;read_default_file&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;/path/to/my.cnf&#39;</span><span class=\"p\">,</span>\n        <span class=\"p\">},</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n\n\n<span class=\"c1\"># my.cnf</span>\n<span class=\"p\">[</span>client<span class=\"p\">]</span>\ndatabase <span class=\"o\">=</span> NAME\nuser <span class=\"o\">=</span> USER\npassword <span class=\"o\">=</span> PASSWORD\ndefault<span class=\"o\">-</span>character<span class=\"o\">-</span><span class=\"nb\">set</span> <span class=\"o\">=</span> utf8\n</code></pre></div>\n<p>Quelques autres options de connexion MySQLdb peuvent se révéler utiles, telles que <code class=\"docutils literal notranslate\">ssl</code>, <code class=\"docutils literal notranslate\">init_command</code> ou <code class=\"docutils literal notranslate\">sql_mode</code>.</p>\n<section id=\"setting-sql-mode\">\n<span id=\"mysql-sql-mode\"></span><h4>Définition de <code class=\"docutils literal notranslate\">sql_mode</code><a class=\"heading-anchor\" href=\"#setting-sql-mode\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>À partir de MySQL 5.7 et pour les nouvelles installations de MySQL 5.6, la valeur par défaut de l’option <code class=\"docutils literal notranslate\">sql_mode</code> contient <code class=\"docutils literal notranslate\">STRICT_TRANS_TABLES</code>. Cette option transforme les avertissements en erreurs lorsque des données sont tronquées lors de leur insertion. Django recommande fortement d’activer un <a class=\"reference external\" href=\"https://dev.mysql.com/doc/refman/en/sql-mode.html#sql-mode-strict\">mode strict</a> pour MySQL afin d’éviter des pertes de données (<code class=\"docutils literal notranslate\">STRICT_TRANS_TABLES</code> ou <code class=\"docutils literal notranslate\">STRICT_ALL_TABLES</code>).</p>\n<p>SI vous avez besoin de personnaliser le mode SQL, vuos pouvez définir la variable <code class=\"docutils literal notranslate\">sql_mode</code> comme toute autre option MySQL : soit dans un fichier de configuration, soit par la ligne <code class=\"docutils literal notranslate\">'init_command': &quot;SET sql_mode='STRICT_TRANS_TABLES'&quot;</code> dans la partie <a class=\"reference internal\" href=\"/fr/1.11/ref/settings/#std-setting-OPTIONS\"><code class=\"xref std std-setting docutils literal notranslate\">OPTIONS</code></a> de la configuration de base de données dans <a class=\"reference internal\" href=\"/fr/1.11/ref/settings/#std-setting-DATABASES\"><code class=\"xref std std-setting docutils literal notranslate\">DATABASES</code></a>.</p>\n</section>\n<section id=\"mysql-isolation-level\">\n<span id=\"id11\"></span><h4>Niveau d’isolement<a class=\"heading-anchor\" href=\"#mysql-isolation-level\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<aside class=\"version-note version-added\" data-version=\"1.11\" role=\"note\">\n<p class=\"version-note-title\">New in Django 1.11</p></aside>\n<p>Lors d’un fonctionnement avec charge concurrentielle, les transactions de base de données de différentes sessions (par exemple des fils d’exécution séparés traitant différentes requêtes) peuvent interagir entre elles. Ces interactions sont affectées par le <a class=\"reference external\" href=\"https://dev.mysql.com/doc/refman/en/innodb-transaction-isolation-levels.html\">niveau d’isolation de transaction</a> de chaque session. Il est possible de définir le niveau d’isolation de transaction d’une connexion avec la clé <code class=\"docutils literal notranslate\">'isolation_level'</code> de la partie <a class=\"reference internal\" href=\"/fr/1.11/ref/settings/#std-setting-OPTIONS\"><code class=\"xref std std-setting docutils literal notranslate\">OPTIONS</code></a> de la configuration de base de données dans <a class=\"reference internal\" href=\"/fr/1.11/ref/settings/#std-setting-DATABASES\"><code class=\"xref std std-setting docutils literal notranslate\">DATABASES</code></a>. Les valeurs autorisées pour cette clé sont les quatre niveaux d’isolation standards :</p>\n<ul class=\"simple\">\n<li><p><code class=\"docutils literal notranslate\">'read uncommitted'</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">'read committed'</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">'repeatable read'</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">'serializable'</code></p></li>\n</ul>\n<p>ou <code class=\"docutils literal notranslate\">None</code> pour utiliser le niveau d’isolation configuré sur le serveur. Cependant, Django fonctionne mieux avec <code class=\"docutils literal notranslate\">read committed</code> plutôt que la valeur par défaut de MySQL qui est <code class=\"docutils literal notranslate\">repeatable read</code>. Des pertes de données sont possibles avec le niveau <code class=\"docutils literal notranslate\">repeatable read</code>.</p>\n</section>\n</section>\n<section id=\"creating-your-tables\">\n<h3>Création des tables<a class=\"heading-anchor\" href=\"#creating-your-tables\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Lorsque Django génère le schéma, il ne précise pas de moteur de stockage, donc les tables seront créées avec le moteur de stockage par défaut de votre serveur de base de données. La solution la plus simple est de définir le moteur souhaité comme moteur de stockage par défaut pour votre serveur de base de données.</p>\n<p>Si vous utilisez un service d’hébergement et que vous ne pouvez pas modifier le moteur de stockage par défaut sur votre serveur, vous avez plusieurs possibilités.</p>\n<ul>\n<li><p>Après la création des tables, exécutez une commande SQL <code class=\"docutils literal notranslate\">ALTER TABLE</code> pour convertir une table vers un nouveau moteur de stockage (comme InnoDB) :</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>ALTER TABLE <span class=\"o\">&lt;</span>tablename<span class=\"o\">&gt;</span> ENGINE<span class=\"o\">=</span>INNODB<span class=\"p\">;</span>\n</code></pre></div>\n<p>Cela peut être fastidieux si vous avez beaucoup de tables.</p>\n</li>\n<li><p>Une autre possibilité est d’utiliser l’option <code class=\"docutils literal notranslate\">init_command</code> de MySQLdb avant de créer les tables :</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=\"s1\">&#39;OPTIONS&#39;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n   <span class=\"s1\">&#39;init_command&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;SET default_storage_engine=INNODB&#39;</span><span class=\"p\">,</span>\n<span class=\"p\">}</span>\n</code></pre></div>\n<p>Ceci définit le moteur de stockage par défaut lors de la connexion à la base de données. Une fois que les tables ont été créées, vous devriez supprimer cette option car elle ajoute une requête lors de chaque connexion à la base de données, alors que c’est uniquement nécessaire lors de la création d’une table.</p>\n</li>\n</ul>\n</section>\n<section id=\"table-names\">\n<h3>Noms de tables<a class=\"heading-anchor\" href=\"#table-names\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Certains <a class=\"reference external\" href=\"https://bugs.mysql.com/bug.php?id=48875\">problèmes connus</a>, même dans les dernières versions de MySQL peuvent engendrer une modification d’un nom de table lorsque certaines instructions SQL sont exécutées sous certaines conditions. Il est recommandé d’utiliser des noms de table en minuscules, si possible, pour éviter les problèmes qui pourraient résulter de ce comportement. Django utilise des noms de tables en minuscules quand il génère automatiquement les noms de table à partir des modèles, c’est donc un élément à prendre en compte surtout si vous surchargez le nom de la table en utilisant le paramètre <a class=\"reference internal\" href=\"/fr/1.11/ref/models/options/#django.db.models.Options.db_table\" title=\"django.db.models.Options.db_table\"><code class=\"xref py py-class docutils literal notranslate\">db_table</code></a>.</p>\n</section>\n<section id=\"savepoints\">\n<h3>Points de sauvegarde (« savepoints »)<a class=\"heading-anchor\" href=\"#savepoints\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>L’ORM de Django tout comme MySQL (lorsque le <a class=\"reference internal\" href=\"#mysql-storage-engines\"><span class=\"std std-ref\">moteur de stockage</span></a> InnoDB est utilisé) prennent en charge les <a class=\"reference internal\" href=\"/fr/1.11/topics/db/transactions/#topics-db-transactions-savepoints\"><span class=\"std std-ref\">points de sauvegarde</span></a> des bases de données.</p>\n<p>Si vous utilisez le moteur de stockage MyISAM, vous recevrez des erreurs générées par la base de données si vous essayez d’utiliser les <a class=\"reference internal\" href=\"/fr/1.11/topics/db/transactions/#topics-db-transactions-savepoints\"><span class=\"std std-ref\">méthodes de l’API des transactions liées aux points de sauvegarde</span></a>.  En effet, comme la détection du moteur de stockage d’une table ou d’une base de données MySQL est une opération très coûteuse en ressources, il a été décidé de ne pas convertir dynamiquement ces méthodes en méthodes neutres en se basant sur ce genre de détection.</p>\n</section>\n<section id=\"notes-on-specific-fields\">\n<h3>Notes sur des champs particuliers<a class=\"heading-anchor\" href=\"#notes-on-specific-fields\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<section id=\"character-fields\">\n<h4>Champs de type caractère<a class=\"heading-anchor\" href=\"#character-fields\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Tous les champs qui sont stockés dans des types de colonnes <code class=\"docutils literal notranslate\">VARCHAR</code> ont leur taille maximale (<code class=\"docutils literal notranslate\">max_length</code>) limitée à 255 caractères si vous utilisez <code class=\"docutils literal notranslate\">unique=True</code> pour ce champ. Cela concerne les champs <a class=\"reference internal\" href=\"/fr/1.11/ref/models/fields/#django.db.models.CharField\" title=\"django.db.models.CharField\"><code class=\"xref py py-class docutils literal notranslate\">CharField</code></a>, <a class=\"reference internal\" href=\"/fr/1.11/ref/models/fields/#django.db.models.SlugField\" title=\"django.db.models.SlugField\"><code class=\"xref py py-class docutils literal notranslate\">SlugField</code></a> et <a class=\"reference internal\" href=\"/fr/1.11/ref/models/fields/#django.db.models.CommaSeparatedIntegerField\" title=\"django.db.models.CommaSeparatedIntegerField\"><code class=\"xref py py-class docutils literal notranslate\">CommaSeparatedIntegerField</code></a>.</p>\n</section>\n<section id=\"textfield-limitations\">\n<h4>Limites des champs<a class=\"heading-anchor\" href=\"#textfield-limitations\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>MySQL ne peut indexer que les N premiers caractères d’une colonne <code class=\"docutils literal notranslate\">BLOB</code> ou <code class=\"docutils literal notranslate\">TEXT</code>. Comme <code class=\"docutils literal notranslate\">TextField</code> n’a pas de longueur définie, il n’est pas possible de marquer un tel champ avec <code class=\"docutils literal notranslate\">unique=True</code>. MySQL produirait l’erreur : « BLOB/TEXT column “&lt;db_column&gt;” used in key specification without a key length ».</p>\n</section>\n<section id=\"fractional-seconds-support-for-time-and-datetime-fields\">\n<span id=\"mysql-fractional-seconds\"></span><h4>Prise en charge des fractions de secondes pour les champs heure et date/heure<a class=\"heading-anchor\" href=\"#fractional-seconds-support-for-time-and-datetime-fields\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>À partir de la version 5.6.4, MySQL est capable de stocker des fractions de secondes, pour autant que les définitions de colonnes contiennent une indication adéquate (par ex.  <code class=\"docutils literal notranslate\">DATETIME(6)</code>). Dans les versions précédentes, ce n’était pas pris en charge du tout. De plus, les versions de MySQLdb plus anciennes que 1.2.5 contiennent <a class=\"reference external\" href=\"https://github.com/farcepest/MySQLdb1/issues/24\">une anomalie</a> qui empêche également l’utilisation des fractions de secondes avec MySQL.</p>\n<p>Django ne va pas mettre à jour lui-même les colonnes existantes pour que les fractions de secondes soient incluses si le serveur de base de données le prend en charge. Si vous souhaitez les activer dans une base de données existante, c’est à vous de mettre à jour la colonne manuellement dans la base de données en exécutant une commande du style :</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>ALTER TABLE `your_table` MODIFY `your_datetime_column` DATETIME(6)\n</code></pre></div>\n<p>ou en utilisant une opération <a class=\"reference internal\" href=\"/fr/1.11/ref/migration-operations/#django.db.migrations.operations.RunSQL\" title=\"django.db.migrations.operations.RunSQL\"><code class=\"xref py py-class docutils literal notranslate\">RunSQL</code></a> dans une <a class=\"reference internal\" href=\"/fr/1.11/topics/migrations/#data-migrations\"><span class=\"std std-ref\">migration de données</span></a>.</p>\n</section>\n<section id=\"timestamp-columns\">\n<h4>Colonnes <code class=\"docutils literal notranslate\">TIMESTAMP</code><a class=\"heading-anchor\" href=\"#timestamp-columns\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Si vous utilisez une base de données existante qui contient des colonnes <code class=\"docutils literal notranslate\">TIMESTAMP</code>, vous devez définir <a class=\"reference internal\" href=\"/fr/1.11/ref/settings/#std-setting-USE_TZ\"><code class=\"xref std std-setting docutils literal notranslate\">USE_TZ = False</code></a> pour éviter de corrompre des données. <a class=\"reference internal\" href=\"/fr/1.11/ref/django-admin/#django-admin-inspectdb\"><code class=\"xref std std-djadmin docutils literal notranslate\">inspectdb</code></a> fait correspondre ces colonnes à des champs <a class=\"reference internal\" href=\"/fr/1.11/ref/models/fields/#django.db.models.DateTimeField\" title=\"django.db.models.DateTimeField\"><code class=\"xref py py-class docutils literal notranslate\">DateTimeField</code></a> et si vous activez la prise en charge des fuseaux horaires, aussi bien MySQL que Django vont tenter de convertir les valeurs depuis le fuseau UTC vers le temps local.</p>\n</section>\n</section>\n<section id=\"row-locking-with-queryset-select-for-update\">\n<h3>Verrouillage de ligne avec <code class=\"docutils literal notranslate\">QuerySet.select_for_update()</code><a class=\"heading-anchor\" href=\"#row-locking-with-queryset-select-for-update\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>MySQL ne gère pas les options <code class=\"docutils literal notranslate\">NOWAIT</code> et <code class=\"docutils literal notranslate\">SKIP LOCKED</code> de l’instruction <code class=\"docutils literal notranslate\">SELECT ... FOR UPDATE</code>. Si <code class=\"docutils literal notranslate\">select_for_update()</code> est utilisé avec <code class=\"docutils literal notranslate\">nowait=True</code> ou <code class=\"docutils literal notranslate\">skip_locked=True</code>, une exception de type <code class=\"docutils literal notranslate\">DatabaseError</code> sera générée.</p>\n</section>\n<section id=\"automatic-typecasting-can-cause-unexpected-results\">\n<h3>Le retypage automatique peut produire des résultats inattendus<a class=\"heading-anchor\" href=\"#automatic-typecasting-can-cause-unexpected-results\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Lors de l’exécution d’une requête sur un type chaîne mais avec une valeur nombre entier, MySQL force les types de toutes les valeurs de la table à des nombres entiers avant d’effectuer la comparaison. Si la table contient les valeurs <code class=\"docutils literal notranslate\">'abc'</code>, <code class=\"docutils literal notranslate\">'def'</code> et que la requête cherche <code class=\"docutils literal notranslate\">WHERE macolonne=0</code>, les deux lignes vont correspondre. De la même manière, <code class=\"docutils literal notranslate\">WHERE macolonne=1</code> correspond à la valeur <code class=\"docutils literal notranslate\">'abc1'</code>. C’est pourquoi les champs de type chaîne inclus dans Django forcent toujours la valeur à une chaîne avant de l’utiliser dans une requête.</p>\n<p>Si vous implémentez des champs de modèle personnalisés héritant directement de <a class=\"reference internal\" href=\"/fr/1.11/ref/models/fields/#django.db.models.Field\" title=\"django.db.models.Field\"><code class=\"xref py py-class docutils literal notranslate\">Field</code></a>, que vous surchargez <a class=\"reference internal\" href=\"/fr/1.11/ref/models/fields/#django.db.models.Field.get_prep_value\" title=\"django.db.models.Field.get_prep_value\"><code class=\"xref py py-meth docutils literal notranslate\">get_prep_value()</code></a> ou que vous utilisez <a class=\"reference internal\" href=\"/fr/1.11/ref/models/expressions/#django.db.models.expressions.RawSQL\" title=\"django.db.models.expressions.RawSQL\"><code class=\"xref py py-class docutils literal notranslate\">RawSQL</code></a>, <a class=\"reference internal\" href=\"/fr/1.11/ref/models/querysets/#django.db.models.query.QuerySet.extra\" title=\"django.db.models.query.QuerySet.extra\"><code class=\"xref py py-meth docutils literal notranslate\">extra()</code></a> ou <a class=\"reference internal\" href=\"/fr/1.11/topics/db/sql/#django.db.models.Manager.raw\" title=\"django.db.models.Manager.raw\"><code class=\"xref py py-meth docutils literal notranslate\">raw()</code></a>, vous devez vous assurer d’effectuer les forçages de type appropriés.</p>\n</section>\n</section>\n<section id=\"sqlite-notes\">\n<span id=\"id12\"></span><h2>Notes sur SQLite<a class=\"heading-anchor\" href=\"#sqlite-notes\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p><a class=\"reference external\" href=\"https://www.sqlite.org/\">SQLite</a> fournit une excellente alternative pour le développement d’applications qui sont essentiellement en lecture seule ou qui nécessitent une installation de plus petite taille. Comme avec tous les serveurs de base de données, cependant, il y a quelques différences spécifiques à SQLite à prendre en compte.</p>\n<section id=\"substring-matching-and-case-sensitivity\">\n<span id=\"sqlite-string-matching\"></span><h3>Recherche de portions de chaînes de caractères et sensibilité à la casse<a class=\"heading-anchor\" href=\"#substring-matching-and-case-sensitivity\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Pour toutes les versions de SQLite, il y a un comportement peu intuitif lorsque l’on essaie de faire correspondre certains types de chaînes. Ce comportement est déclenché lors de l’utilisation des filtres <a class=\"reference internal\" href=\"/fr/1.11/ref/models/querysets/#std-fieldlookup-iexact\"><code class=\"xref std std-lookup docutils literal notranslate\">iexact</code></a> ou <a class=\"reference internal\" href=\"/fr/1.11/ref/models/querysets/#std-fieldlookup-contains\"><code class=\"xref std std-lookup docutils literal notranslate\">contains</code></a> dans des QuerySets. Le comportement se divise en deux cas :</p>\n<p>1. For substring matching, all matches are done case-insensitively. That is a\nfilter such as <code class=\"docutils literal notranslate\">filter(name__contains=&quot;aa&quot;)</code> will match a name of <code class=\"docutils literal notranslate\">&quot;Aabb&quot;</code>.</p>\n<p>2. For strings containing characters outside the ASCII range, all exact string\nmatches are performed case-sensitively, even when the case-insensitive options\nare passed into the query. So the <a class=\"reference internal\" href=\"/fr/1.11/ref/models/querysets/#std-fieldlookup-iexact\"><code class=\"xref std std-lookup docutils literal notranslate\">iexact</code></a> filter will behave exactly\nthe same as the <a class=\"reference internal\" href=\"/fr/1.11/ref/models/querysets/#std-fieldlookup-exact\"><code class=\"xref std std-lookup docutils literal notranslate\">exact</code></a> filter in these cases.</p>\n<p>Il existe quelques solutions de contournement <a class=\"reference external\" href=\"https://www.sqlite.org/faq.html#q18\">documentées sur sqlite.org</a>, mais elles ne sont pas exploitées par le moteur SQLite par défaut de Django, car cela impliquerait des difficultés certaines pour le faire de manière robuste. Django présente donc le comportement SQLite par défaut et il faut en être bien conscient lors de filtrage de sous-chaînes ou de chaînes insensibles à la casse.</p>\n</section>\n<section id=\"old-sqlite-and-case-expressions\">\n<h3>Expressions <code class=\"docutils literal notranslate\">CASE</code> et anciennes versions de SQLite<a class=\"heading-anchor\" href=\"#old-sqlite-and-case-expressions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>SQLite 3.6.23.1 et ses versions précédentes contiennent une anomalie lors du <a class=\"reference external\" href=\"https://code.djangoproject.com/ticket/24148\">traitement des paramètres de requête</a> dans une expression <code class=\"docutils literal notranslate\">CASE</code> contenant une clause <code class=\"docutils literal notranslate\">ELSE</code> et de l’arithmétique.</p>\n<p>SQLite 3.6.23.1 a été publiée en mars 2010 et la plupart des distributions binaires actuelles sur diverses plates-formes contiennent une version plus récente de SQLite, à l’exception notable des installeurs Python 2.7 pour Windows.</p>\n<p>Au moment d’écrire ces lignes, la dernière version pour Windows, Python 2.7.10, inclut SQLite 3.6.21. Vous pouvez installer <code class=\"docutils literal notranslate\">pysqlite2</code> ou remplacer <code class=\"docutils literal notranslate\">sqlite3.dll</code> (installé par défaut dans <code class=\"docutils literal notranslate\">C:\\Python27\\DLLs</code>) par une version plus récente provenant de <a class=\"reference external\" href=\"https://www.sqlite.org/\">https://www.sqlite.org/</a> afin de remédier à ce problème.</p>\n</section>\n<section id=\"using-newer-versions-of-the-sqlite-db-api-2-0-driver\">\n<span id=\"using-newer-versions-of-pysqlite\"></span><h3>Utilisation de versions plus récentes du pilote SQLite DB-API 2.0<a class=\"heading-anchor\" href=\"#using-newer-versions-of-the-sqlite-db-api-2-0-driver\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Django utilise de préférence le module <code class=\"docutils literal notranslate\">pysqlite2</code> au lieu du module <code class=\"docutils literal notranslate\">sqlite3</code> livré avec la bibliothèque Python standard, s’il le trouve installé.</p>\n<p>Cela donne la possibilité de mettre à niveau à la fois l’interface DB-API 2.0 ou SQLite 3 elle-même à des versions plus récentes que celles incluses dans votre distribution Python binaire, si le besoin s’en fait sentir.</p>\n</section>\n<section id=\"database-is-locked-errors\">\n<h3>Erreurs « Database is locked » (la base de données est verrouillée)<a class=\"heading-anchor\" href=\"#database-is-locked-errors\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>SQLite est supposé être une base de données légère et ne peut donc pas gérer un niveau élevé de concurrence. Les erreurs <code class=\"docutils literal notranslate\">OperationalError: database is locked</code> indiquent que l’application subit une concurrence plus élevée que ce que <code class=\"docutils literal notranslate\">sqlite</code> ne peut gérer dans sa configuration par défaut. Cette erreur signifie qu’un processus ou un fil d’exécution possède un verrou exclusif sur la connexion de base de données et qu’un autre fil d’exécution a dû attendre trop longtemps que le verrou se libère.</p>\n<p>L’adaptateur SQLite de Python comporte une valeur d’expiration par défaut qui détermine le temps maximal d’attente de déverrouillage d’un autre fil d’exécution avant qu’il n’expire en générant une erreur <code class=\"docutils literal notranslate\">OperationalError: database is locked</code>.</p>\n<p>Si vous obtenez cette erreur, vous pouvez résoudre le problème en :</p>\n<ul>\n<li><p>Passant à un autre moteur de base de données. À un certain stade, SQLite devient vraiment trop léger pour des applications du monde réel, et ce type d’erreur de concurrence indique que ce point a été atteint.</p></li>\n<li><p>Réécrivant le code pour réduire la concurrence et s’assurer que les transactions de base de données restent aussi brèves que possible.</p></li>\n<li><p>Augmentant la valeur d’expiration par défaut en définissant l’option de base de données <code class=\"docutils literal notranslate\">timeout</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=\"s1\">&#39;OPTIONS&#39;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n    <span class=\"c1\"># ...</span>\n    <span class=\"s1\">&#39;timeout&#39;</span><span class=\"p\">:</span> <span class=\"mi\">20</span><span class=\"p\">,</span>\n    <span class=\"c1\"># ...</span>\n<span class=\"p\">}</span>\n</code></pre></div>\n<p>Cela ne fera que prolonger un peu le temps d’attente de SQLite avant de produire des erreurs « database is locked » ; le problème de base n’en est pas résolu pour autant.</p>\n</li>\n</ul>\n</section>\n<section id=\"queryset-select-for-update-not-supported\">\n<h3><code class=\"docutils literal notranslate\">QuerySet.select_for_update()</code> non pris en charge<a class=\"heading-anchor\" href=\"#queryset-select-for-update-not-supported\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>SQLite ne prend pas en charge la syntaxe <code class=\"docutils literal notranslate\">SELECT ... FOR UPDATE</code>. L’appel de cette méthode n’a aucun effet.</p>\n</section>\n<section id=\"pyformat-parameter-style-in-raw-queries-not-supported\">\n<h3>Le style de paramètre « pyformat » dans les requêtes brutes n’est pas pris en charge<a class=\"heading-anchor\" href=\"#pyformat-parameter-style-in-raw-queries-not-supported\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Pour la plupart des moteurs, les requêtes brutes (<code class=\"docutils literal notranslate\">Manager.raw()</code> ou <code class=\"docutils literal notranslate\">cursor.execute()</code>) peuvent exploiter le style de paramètre « pyformat » où les substituants dans la requête sont écrits sous la forme <code class=\"docutils literal notranslate\">'%(nom)s'</code> et les paramètres sont transmis sous forme de dictionnaire au lieu de liste. SQLite ne prend pas cette syntaxe en charge.</p>\n</section>\n</section>\n<section id=\"oracle-notes\">\n<span id=\"id13\"></span><h2>Notes sur Oracle<a class=\"heading-anchor\" href=\"#oracle-notes\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Django supports <a class=\"reference external\" href=\"https://www.oracle.com/\">Oracle Database Server</a> versions 11.2 and higher. Version\n5.2 through 6.4.1 of the <a class=\"reference external\" href=\"https://oracle.github.io/python-cx_Oracle/\">cx_Oracle</a> Python driver are supported.</p>\n<p>Pour que la commande <code class=\"docutils literal notranslate\">python manage.py migrate</code> fonctionne, l’utilisateur de base de données Oracle doit posséder les permissions d’exécuter les commandes suivantes :</p>\n<ul class=\"simple\">\n<li><p>CREATE TABLE</p></li>\n<li><p>CREATE SEQUENCE</p></li>\n<li><p>CREATE PROCEDURE</p></li>\n<li><p>CREATE TRIGGER</p></li>\n</ul>\n<p>Pour exécuter la suite de tests d’un projet, l’utilisateur doit généralement posséder les privilèges <em>supplémentaires</em> suivants :</p>\n<ul class=\"simple\">\n<li><p>CREATE USER</p></li>\n<li><p>ALTER USER</p></li>\n<li><p>DROP USER</p></li>\n<li><p>CREATE TABLESPACE</p></li>\n<li><p>DROP TABLESPACE</p></li>\n<li><p>CREATE SESSION WITH ADMIN OPTION</p></li>\n<li><p>CREATE TABLE WITH ADMIN OPTION</p></li>\n<li><p>CREATE SEQUENCE WITH ADMIN OPTION</p></li>\n<li><p>CREATE PROCEDURE WITH ADMIN OPTION</p></li>\n<li><p>CREATE TRIGGER WITH ADMIN OPTION</p></li>\n</ul>\n<p>Notez que même si le rôle RESOURCE possède les privilèges requis CREATE TABLE, CREATE SEQUENCE, CREATE PROCEDURE et CREATE TRIGGER et qu’un utilisateur disposant de RESOURCE WITH ADMIN OPTION peut accorder le privilège RESOURCE, cet utilisateur ne peut pas accorder de privilèges individuels (par ex. CREATE TABLE), ce qui fait que  RESOURCE WITH ADMIN OPTION n’est généralement pas suffisant pour exécuter les tests.</p>\n<p>Certaines suites de tests créent aussi des vues ; pour exécuter celles-ci, l’utilisateur a aussi besoin du privilège CREATE VIEW WITH ADMIN OPTION. C’est nécessaire en particulier pour la propre suite de tests de Django.</p>\n<p>Tous ces privilèges sont inclus dans le rôle DBA, qui est adéquat dans le cadre d’une base de données de développement privée.</p>\n<p>Le moteur de base de données Oracle utilise les paquets <code class=\"docutils literal notranslate\">SYS.DBMS_LOB</code> et <code class=\"docutils literal notranslate\">SYS.DBMS_RANDOM</code>, il faut donc que l’utilisateur possède les droits d’exécution pour lui. Il est normalement accessible par défaut à tous les utilisateurs, mais si ce n’est pas le cas, il faut attribuer les permissions comme ceci :</p>\n<div class=\"code-block\" data-language=\"sql\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">SQL</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=\"SQL code\"><code><span class=\"k\">GRANT</span> <span class=\"k\">EXECUTE</span> <span class=\"k\">ON</span> SYS<span class=\"p\">.</span>DBMS_LOB <span class=\"k\">TO</span> <span class=\"k\">user</span><span class=\"p\">;</span>\n<span class=\"k\">GRANT</span> <span class=\"k\">EXECUTE</span> <span class=\"k\">ON</span> SYS<span class=\"p\">.</span>DBMS_RANDOM <span class=\"k\">TO</span> <span class=\"k\">user</span><span class=\"p\">;</span>\n</code></pre></div>\n<section id=\"id14\">\n<h3>Connexion à la base de données<a class=\"heading-anchor\" href=\"#id14\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Pour se connecter en utilisant le nom de service de la base de données Oracle, le fichier <code class=\"docutils literal notranslate\">settings.py</code> doit ressembler à quelque chose 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>DATABASES <span class=\"o\">=</span> <span class=\"p\">{</span>\n    <span class=\"s1\">&#39;default&#39;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n        <span class=\"s1\">&#39;ENGINE&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;django.db.backends.oracle&#39;</span><span class=\"p\">,</span>\n        <span class=\"s1\">&#39;NAME&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;xe&#39;</span><span class=\"p\">,</span>\n        <span class=\"s1\">&#39;USER&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;a_user&#39;</span><span class=\"p\">,</span>\n        <span class=\"s1\">&#39;PASSWORD&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;a_password&#39;</span><span class=\"p\">,</span>\n        <span class=\"s1\">&#39;HOST&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;&#39;</span><span class=\"p\">,</span>\n        <span class=\"s1\">&#39;PORT&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;&#39;</span><span class=\"p\">,</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</code></pre></div>\n<p>Dans ce cas, il faut laisser vide les deux clés <a class=\"reference internal\" href=\"/fr/1.11/ref/settings/#std-setting-HOST\"><code class=\"xref std std-setting docutils literal notranslate\">HOST</code></a> et <a class=\"reference internal\" href=\"/fr/1.11/ref/settings/#std-setting-PORT\"><code class=\"xref std std-setting docutils literal notranslate\">PORT</code></a>. Cependant, si vous n’utilisez pas de fichier <code class=\"docutils literal notranslate\">tnsnames.ora</code> ou une méthode de nommage similaire et que vous vouliez vous connecter en utilisant le SID (« xe » dans cet exemple), remplissez alors à la fois <a class=\"reference internal\" href=\"/fr/1.11/ref/settings/#std-setting-HOST\"><code class=\"xref std std-setting docutils literal notranslate\">HOST</code></a> et <a class=\"reference internal\" href=\"/fr/1.11/ref/settings/#std-setting-PORT\"><code class=\"xref std std-setting docutils literal notranslate\">PORT</code></a>, 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>DATABASES <span class=\"o\">=</span> <span class=\"p\">{</span>\n    <span class=\"s1\">&#39;default&#39;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n        <span class=\"s1\">&#39;ENGINE&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;django.db.backends.oracle&#39;</span><span class=\"p\">,</span>\n        <span class=\"s1\">&#39;NAME&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;xe&#39;</span><span class=\"p\">,</span>\n        <span class=\"s1\">&#39;USER&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;a_user&#39;</span><span class=\"p\">,</span>\n        <span class=\"s1\">&#39;PASSWORD&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;a_password&#39;</span><span class=\"p\">,</span>\n        <span class=\"s1\">&#39;HOST&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;dbprod01ned.mycompany.com&#39;</span><span class=\"p\">,</span>\n        <span class=\"s1\">&#39;PORT&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;1540&#39;</span><span class=\"p\">,</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</code></pre></div>\n<p>Il faut soit remplir les deux clés <a class=\"reference internal\" href=\"/fr/1.11/ref/settings/#std-setting-HOST\"><code class=\"xref std std-setting docutils literal notranslate\">HOST</code></a> et <a class=\"reference internal\" href=\"/fr/1.11/ref/settings/#std-setting-PORT\"><code class=\"xref std std-setting docutils literal notranslate\">PORT</code></a>, soit les laisser toutes deux vides. Django utilise un descripteur de connexion différent en fonction de ce choix.</p>\n</section>\n<section id=\"threaded-option\">\n<h3>Option threaded<a class=\"heading-anchor\" href=\"#threaded-option\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Si vous prévoyez de faire fonctionner Django dans un environnement à fils d’exécution multiples (multithread), par exemple avec Apache et le module MPM par défaut sur tout système d’exploitation moderne), vous <strong>devez</strong> définir à <code class=\"docutils literal notranslate\">True</code> l’option <code class=\"docutils literal notranslate\">threaded</code> de votre configuration de base de données Oracle :</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=\"s1\">&#39;OPTIONS&#39;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n    <span class=\"s1\">&#39;threaded&#39;</span><span class=\"p\">:</span> <span class=\"kc\">True</span><span class=\"p\">,</span>\n<span class=\"p\">},</span>\n</code></pre></div>\n<p>Si vous ne le faites pas, vous risquez d’obtenir des plantées et d’autres comportements bizarres.</p>\n</section>\n<section id=\"insert-returning-into\">\n<h3>INSERT … RETURNING INTO<a class=\"heading-anchor\" href=\"#insert-returning-into\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Par défaut, le moteur Oracle utilise une clause <code class=\"docutils literal notranslate\">RETURNING INTO</code> pour obtenir efficacement la valeur d’un champ <code class=\"docutils literal notranslate\">AutoField</code> lors de l’insertion de nouvelles lignes. Ce comportement peut aboutir à des erreurs <code class=\"docutils literal notranslate\">DatabaseError</code> dans certaines configurations particulières, comme lors de l’insertion dans une table distante ou dans une vue avec le déclencheur <code class=\"docutils literal notranslate\">INSTEAD OF</code>. La clause <code class=\"docutils literal notranslate\">RETURNING INTO</code> peut être désactivée en définissant l’option <code class=\"docutils literal notranslate\">use_returning_into</code> de la configuration de base de données à <code class=\"docutils literal notranslate\">False</code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"s1\">&#39;OPTIONS&#39;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n    <span class=\"s1\">&#39;use_returning_into&#39;</span><span class=\"p\">:</span> <span class=\"kc\">False</span><span class=\"p\">,</span>\n<span class=\"p\">},</span>\n</code></pre></div>\n<p>Dans ce cas, le moteur Oracle utilise une requête <code class=\"docutils literal notranslate\">SELECT</code> séparée pour récupérer les valeurs <code class=\"docutils literal notranslate\">AutoField</code>.</p>\n</section>\n<section id=\"naming-issues\">\n<h3>Questions de nommage<a class=\"heading-anchor\" href=\"#naming-issues\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Oracle impose une longueur limite de 30 caractères pour les noms. Pour respecter cela, le moteur tronque les identifiants de base de données si nécessaire, remplaçant les quatre caractères finaux du nom tronqué par une valeur de hachage MD5 reproductible. De plus, le moteur transforme les identifiants de base de données tout en majuscules.</p>\n<p>Pour empêcher ces transformations (ce qui n’est généralement nécessaire que lorsqu’on a affaire à des bases de données existantes ou quand il faut accéder à des tables appartenant à d’autres utilisateurs), entourez la valeur de <code class=\"docutils literal notranslate\">db_table</code> par des guillemets :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span> <span class=\"nc\">LegacyModel</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    <span class=\"k\">class</span> <span class=\"nc\">Meta</span><span class=\"p\">:</span>\n        db_table <span class=\"o\">=</span> <span class=\"s1\">&#39;&quot;name_left_in_lowercase&quot;&#39;</span>\n\n<span class=\"k\">class</span> <span class=\"nc\">ForeignModel</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    <span class=\"k\">class</span> <span class=\"nc\">Meta</span><span class=\"p\">:</span>\n        db_table <span class=\"o\">=</span> <span class=\"s1\">&#39;&quot;OTHER_USER&quot;.&quot;NAME_ONLY_SEEMS_OVER_30&quot;&#39;</span>\n</code></pre></div>\n<p>Les noms entre guillemets peuvent également être utilisés avec les autres moteurs de base de données pris en charge par Django ; mais ces guillemets n’ont un effet qu’avec Oracle.</p>\n<p>Lors de l’exécution de <code class=\"docutils literal notranslate\">migrate</code>, une erreur <code class=\"docutils literal notranslate\">ORA-06552</code> peut se produire si certains mots-clés Oracle sont employés comme noms de champs de modèle ou comme valeur de l’option <code class=\"docutils literal notranslate\">db_column</code>. Django place entre guillemets tous les identifiants utilisés dans les requêtes pour empêcher la plupart de ce genre de problèmes, mais cette erreur peut quand même se produire lorsqu’un type de données Oracle est utilisé comme nom de colonne. Plus particulièrement, essayez d’éviter d’utiliser les noms <code class=\"docutils literal notranslate\">date</code>, <code class=\"docutils literal notranslate\">timestamp</code>, <code class=\"docutils literal notranslate\">number</code> ou <code class=\"docutils literal notranslate\">float</code> comme noms de champs.</p>\n</section>\n<section id=\"null-and-empty-strings\">\n<h3>NULL et les chaînes vides<a class=\"heading-anchor\" href=\"#null-and-empty-strings\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Django préfère généralement utiliser la chaîne vide (“”) plutôt que NULL, mais Oracle considère ces deux valeurs comme identiques. Pour contourner cela, le moteur Oracle ignore l’option explicite <code class=\"docutils literal notranslate\">null</code> pour les champs où la chaîne vide est une valeur possible et génère les instructions SQL comme si <code class=\"docutils literal notranslate\">null=True</code>. Lors de la lecture à partir de la base de données, Django part du principe qu’une valeur <code class=\"docutils literal notranslate\">NULL</code> dans l’un de ces champs équivaut en réalité à la chaîne vide et les données sont silencieusement converties pour respecter ce principe.</p>\n</section>\n<section id=\"id15\">\n<h3>Limites des champs<a class=\"heading-anchor\" href=\"#id15\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Le moteur Oracle stocke les champs <code class=\"docutils literal notranslate\">TextFields</code> dans des colonnes <code class=\"docutils literal notranslate\">NCLOB</code>. Oracle impose certaines limites à l’utilisation de telles colonnes LOB en général :</p>\n<ul class=\"simple\">\n<li><p>Les colonnes LOB ne peuvent pas être utilisées comme clés primaires.</p></li>\n<li><p>Les colonnes LOB ne peuvent pas être utilisées dans les index.</p></li>\n<li><p>Les colonnes LOB ne peuvent pas être utilisées dans une liste <code class=\"docutils literal notranslate\">SELECT DISTINCT</code>. Cela signifie qu’une tentative d’utiliser la méthode <code class=\"docutils literal notranslate\">QuerySet.distinct</code> pour un modèle qui contient des colonnes <code class=\"docutils literal notranslate\">TextField</code> produira une erreur <code class=\"docutils literal notranslate\">ORA-00932``avec Oracle. Pour contourner ce problème, utilisez la méthode ``QuerySet.defer</code> de concert avec <code class=\"docutils literal notranslate\">distinct()</code> afin d’éviter que des colonnes <code class=\"docutils literal notranslate\">TextField</code> ne se retrouvent incluses dans la liste <code class=\"docutils literal notranslate\">SELECT DISTINCT</code>.</p></li>\n</ul>\n</section>\n</section>\n<section id=\"using-a-3rd-party-database-backend\">\n<span id=\"third-party-notes\"></span><h2>Utilisation d’un moteur de base de données externe<a class=\"heading-anchor\" href=\"#using-a-3rd-party-database-backend\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>En plus des bases de données prises en charge officiellement, il existe des moteurs externes à Django qui permettent d’utiliser d’autres bases de données avec Django :</p>\n<ul class=\"simple\">\n<li><p><a class=\"reference external\" href=\"https://github.com/sqlanywhere/sqlany-django\">SAP SQL Anywhere</a></p></li>\n<li><p><a class=\"reference external\" href=\"https://pypi.python.org/pypi/ibm_db/\">IBM DB2</a></p></li>\n<li><p><a class=\"reference external\" href=\"https://django-mssql.readthedocs.io/en/latest/\">Microsoft SQL Server</a></p></li>\n<li><p><a class=\"reference external\" href=\"https://github.com/maxirobaina/django-firebird\">Firebird</a></p></li>\n<li><p><a class=\"reference external\" href=\"https://github.com/lionheart/django-pyodbc/\">ODBC</a></p></li>\n</ul>\n<p>Les versions de Django et les fonctionnalités ORM prises en charges par ces moteurs inofficiels varient considérablement. Si vous avez des questions concernant les capacités spécifiques de ces moteurs inofficiels ou des questions de support, vous devrez vous adresser aux canaux d’aide offerts par chacun de ces projets externes.</p>\n</section>","rootId":"databases","toc":[{"title":"Remarques générales","anchor":"general-notes","children":[{"title":"Connexions persistantes","anchor":"persistent-connections","children":[{"title":"Gestion des connexions","anchor":"connection-management","children":[]},{"title":"Mises en garde","anchor":"caveats","children":[]}]},{"title":"Codage de caractères","anchor":"encoding","children":[]}]},{"title":"Notes sur PostgreSQL","anchor":"postgresql-notes","children":[{"title":"Paramètres de connexion PostgreSQL","anchor":"postgresql-connection-settings","children":[]},{"title":"Optimisation de la configuration de PostgreSQL","anchor":"optimizing-postgresql-s-configuration","children":[]},{"title":"Niveau d’isolement","anchor":"isolation-level","children":[]},{"title":"Index pour les colonnes varchar et text","anchor":"indexes-for-varchar-and-text-columns","children":[]},{"title":"Opération de migration pour ajouter des extensions","anchor":"migration-operation-for-adding-extensions","children":[]},{"title":"Curseurs côté serveur","anchor":"server-side-cursors","children":[{"title":"Transactions groupées et curseurs côté serveur","anchor":"transaction-pooling-and-server-side-cursors","children":[]}]},{"title":"Indication manuelle des valeurs de clé primaire avec autoincrémentation","anchor":"manually-specifying-values-of-auto-incrementing-primary-keys","children":[]},{"title":"Modèles de base de données de test","anchor":"test-database-templates","children":[]},{"title":"Accélération de l’exécution des tests par des réglages temporaires","anchor":"speeding-up-test-execution-with-non-durable-settings","children":[]}]},{"title":"Notes sur MySQL","anchor":"mysql-notes","children":[{"title":"Versions prises en charge","anchor":"version-support","children":[]},{"title":"Les moteurs de stockage","anchor":"storage-engines","children":[]},{"title":"Pilotes DB API MySQL","anchor":"mysql-db-api-drivers","children":[{"title":"MySQLdb","anchor":"id8","children":[]},{"title":"mysqlclient","anchor":"id9","children":[]},{"title":"MySQL Connector/Python","anchor":"id10","children":[]}]},{"title":"Définitions de fuseaux horaires","anchor":"time-zone-definitions","children":[]},{"title":"Création d’une base de données","anchor":"creating-your-database","children":[{"title":"Paramètres de tri","anchor":"collation-settings","children":[]}]},{"title":"Connexion à la base de données","anchor":"connecting-to-the-database","children":[{"title":"Définition de sql_mode","anchor":"setting-sql-mode","children":[]},{"title":"Niveau d’isolement","anchor":"mysql-isolation-level","children":[]}]},{"title":"Création des tables","anchor":"creating-your-tables","children":[]},{"title":"Noms de tables","anchor":"table-names","children":[]},{"title":"Points de sauvegarde (« savepoints »)","anchor":"savepoints","children":[]},{"title":"Notes sur des champs particuliers","anchor":"notes-on-specific-fields","children":[{"title":"Champs de type caractère","anchor":"character-fields","children":[]},{"title":"Limites des champs","anchor":"textfield-limitations","children":[]},{"title":"Prise en charge des fractions de secondes pour les champs heure et date/heure","anchor":"fractional-seconds-support-for-time-and-datetime-fields","children":[]},{"title":"Colonnes TIMESTAMP","anchor":"timestamp-columns","children":[]}]},{"title":"Verrouillage de ligne avec QuerySet.select_for_update()","anchor":"row-locking-with-queryset-select-for-update","children":[]},{"title":"Le retypage automatique peut produire des résultats inattendus","anchor":"automatic-typecasting-can-cause-unexpected-results","children":[]}]},{"title":"Notes sur SQLite","anchor":"sqlite-notes","children":[{"title":"Recherche de portions de chaînes de caractères et sensibilité à la casse","anchor":"substring-matching-and-case-sensitivity","children":[]},{"title":"Expressions CASE et anciennes versions de SQLite","anchor":"old-sqlite-and-case-expressions","children":[]},{"title":"Utilisation de versions plus récentes du pilote SQLite DB-API 2.0","anchor":"using-newer-versions-of-the-sqlite-db-api-2-0-driver","children":[]},{"title":"Erreurs « Database is locked » (la base de données est verrouillée)","anchor":"database-is-locked-errors","children":[]},{"title":"QuerySet.select_for_update() non pris en charge","anchor":"queryset-select-for-update-not-supported","children":[]},{"title":"Le style de paramètre « pyformat » dans les requêtes brutes n’est pas pris en charge","anchor":"pyformat-parameter-style-in-raw-queries-not-supported","children":[]}]},{"title":"Notes sur Oracle","anchor":"oracle-notes","children":[{"title":"Connexion à la base de données","anchor":"id14","children":[]},{"title":"Option threaded","anchor":"threaded-option","children":[]},{"title":"INSERT … RETURNING INTO","anchor":"insert-returning-into","children":[]},{"title":"Questions de nommage","anchor":"naming-issues","children":[]},{"title":"NULL et les chaînes vides","anchor":"null-and-empty-strings","children":[]},{"title":"Limites des champs","anchor":"id15","children":[]}]},{"title":"Utilisation d’un moteur de base de données externe","anchor":"using-a-3rd-party-database-backend","children":[]}],"breadcrumbs":[{"docname":"ref/index","title":"Référence de l’API","url":"/fr/1.11/ref/"}],"prev":{"docname":"ref/csrf","title":"Protection contre le « Cross site request forgery » (CSRF)","url":"/fr/1.11/ref/csrf/"},"next":{"docname":"ref/django-admin","title":"django-admin et manage.py","url":"/fr/1.11/ref/django-admin/"},"formats":{"html":"/fr/1.11/ref/databases/","markdown":"/fr/1.11/ref/databases.md","json":"/fr/1.11/ref/databases.json"},"source":"https://github.com/django/django/blob/stable/1.11.x/docs/ref/databases.txt","official":"https://docs.djangoproject.com/fr/1.11/ref/databases/","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","fr","ja","id","pt-br","ko","es","el","pl"]}