[PYTHON] Utilisation: Django-MySQL

Cet article est le 5ème jour du Calendrier de l'Avent Django 2019.

introduction

L'ORM de Django peut émettre plus qu'assez de requêtes pour le développement en utilisant pleinement les objets select_related, prefetch_related, Preftch, Q, etc.

Cependant, certaines choses ne peuvent pas être effectuées et, dans certains cas, vous devez écrire du SQL brut. Par exemple, si vous avez plusieurs index, spécifiez l'index que vous souhaitez utiliser, ʻUSE_IDNEX, ou spécifiez l'index que vous ne voulez pas utiliser, ʻIGNORE_INDEX. Dans ce cas, vous devez écrire du SQL brut.

Django-MySQL

Cependant, en utilisant ce Django-MySQL, vous pouvez étendre l'ORM de Django sans écrire de SQL brut et émettre des requêtes telles que ʻUSE_IDNEX et ʻIGNORE_INDEX.

installer

Installation

pip install django-mysql

Modifier les paramètres.py

Ajouter django-mysql à INSTALLED_APPS


INSTALLED_APPS = (
    "django.contrib.admin",
    "django.contrib.auth",
    ...
    ...
    "django_mysql",
)

Activer DJANGO_MYSQL_REWRITE_QUERIES


DJANGO_MYSQL_REWRITE_QUERIES = True

Définition de sql_mode et innodb_strict_mode

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.mysql",
        "HOST": "127.0.0.1",
        "NAME": "hogehoge",
        "USER": "fugafuga",
        "OPTIONS": {
            "charset": "utf8mb4",
            "init_command": "SET sql_mode='STRICT_TRANS_TABLES', innodb_strict_mode=1",
        },
    }
}

Notez que cette modification entraînera une erreur lors de la tentative d'insertion / mise à jour de données dépassant max_length lorsque le mode STRICT est activé. Si vous n'activez pas le mode STRICT, si vous insérez / mettez à jour des données qui dépassent max_length, l'excédent sera tronqué et traité sans erreur, donc si vous ne l'avez pas correctement validé. Besoin d'être prudent.

Notez que ce changement est un paramètre lors de la connexion à MySQL depuis Django, il n'est donc pas nécessaire de remigrer ou quelque chose du genre.

Utilisons

paramètres du modèle

Créons un modèle appelé hoge dans l'application des utilisateurs. Mettez un index sur «fuga» et «piyo» du champ.

users/hoge.py


from django.db import models
from django_mysql.models import QuerySet


class Hoge(models.Model):
    fuga = models.IntegerField(db_index=True)
    piyo = models.IntegerField(db_index=True)

    objects = QuerySet.as_manager()

La différence est que vous pouvez faire à partir de django_mysql.models importer QuerySet et l'utiliser comme gestionnaire ORM. En faisant cela, vous pouvez émettre des requêtes étendues dans Django-MySQL.

Informations sur la table créée

mysql> show index from users_hoge;
+------------+------------+--------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table      | Non_unique | Key_name                 | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+------------+------------+--------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| users_hoge |          0 | PRIMARY                  |            1 | id          | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
| users_hoge |          1 | users_hoge_fuga_8a4fba19 |            1 | fuga        | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
| users_hoge |          1 | users_hoge_piyo_4539c423 |            1 | piyo        | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
+------------+------------+--------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

C'est comme ça.

Essayez IGNORE INDEX

Dans le cas de l'émission d'une requête sans utiliser l'index fuga, procédez comme suit.

python


Hoge.objects.all().ignore_index("users_hoge_fuga_8a4fba19")

Le SQL émis par ceci est le suivant

SELECT
  `users_hoge`.`id`,
  `users_hoge`.`fuga`,
  `users_hoge`.`piyo`
FROM
  `users_hoge` IGNORE INDEX(`users_hoge_fuga_8a4fba19`);

L'index ignorer a été émis correctement.

Si vous essayez de le faire sans utiliser Django-MySQL

AttributeError: 'QuerySet' object has no attribute 'ignore_index'

J'obtiens une erreur comme celle-ci.

fin

Jusqu'à présent, je n'ai utilisé que IGNORE INDEX, mais je peux utiliser l'index de force et d'autres fonctions utiles, veuillez donc vous référer à [Documentation](https://django-mysql.readthedocs.io/en/latest] pour plus de détails. Veuillez lire /index.html). Vous pouvez envisager d'introduire Djnago-MySQL une fois lorsque vous rencontrez un cas où vous devez écrire du SQL avec une mesure minutieuse qui ne peut pas être réalisée avec un ORM normal.

De côté

Est-ce un logo chaque fois que vous le voyez? Ou plutôt, le personnage est mauvais. image.png

Recommended Posts

Utilisation: Django-MySQL
Utilisez DeepLabCut
Utiliser pycscope
Utilisez des collections.
Utilisez Pygments.rb
Utilisez Numpy
Utilisez pandas-ply
Utilisez GitPython
Utiliser Miniconda
Pourquoi utiliser Linux
[C] Utilisez qsort ()
Utilisons pytube
Utiliser l'API JIRA
Utiliser django-debug-toolbar de manière non locale
Utiliser l'optimisation des combinaisons