Skip to main content
BlogBases de donnéesComment Django fait le gros du travail pour SQL

Comment Django fait le gros du travail pour SQL

Comment Django fait le gros du travail - En-tête de blog

Pythonet surtout Django, sont essentiels pour construire des applications plus efficaces, avec moins de code, et connectées à une base de données hautement évolutive. Je suis ici pour vous parler de la réduction de la friction quotidienne qui vient avec la construction et le soutien des applications modernes en utilisant SQL et Python pour abstraire la complexité et rendre notre travail et nos vies un peu plus faciles.

Sans entrer dans les détails, nous pouvons supposer :

  • SQL est optimisé pour les bases de données SQL
  • Python n ' est pas optimisé pour les bases de données SQL

Cet exercice soutient directement l'ebook Understanding Databases et ma nouvelle série éducative Linode LIVE ! en utilisant Python et l'outillage Pythonic pour exécuter des commandes en SQL brut sans avoir besoin d'écrire du SQL. J'utilise la modélisation de données de Django, mais la syntaxe est très similaire à celle du package SQLAlchemy de Python.

Commençons !
Voici un exemple de modèle de données Django :

class BlogArticle(models.Model):
    user = models.ForeignKey(User, default=1, on_delete=models.SET_DEFAULT)
    title = models.CharField(max_length=120)
    slug = models.SlugField(blank=True, null=True)
    content = models.TextField(blank=True, null=True)
    publish_timestamp = models.DateTimeField(
        auto_now_add=False,
        auto_now=False,
        blank=True,
        null=True,
    )

Supposons que ce modèle se trouve dans une application Django appelée Articles (Les applications Django sont essentiellement des composants qui constituent l'intégralité d'un projet Django).

Nous avons donc maintenant deux noms avec lesquels travailler :

  • Articles (nom de l'application)
  • BlogArticle (nom du modèle)

Combinés, ils se traduisent par le nom de la table SQL :

articles_blog_article

Django fait cette magie pour nous.

Si nous utilisions le shell MySQL, nous verrions :

mysql> SHOW TABLES;
+------------------------------+
| Tables_in_cfe_django_blog_db |
+------------------------------+
| articles_blog_article        |
| auth_group                   |
| auth_group_permissions       |
| auth_permission              |
| auth_user                    |
| auth_user_groups             |
| auth_user_user_permissions   |
| django_admin_log             |
| django_content_type          |
| django_migrations            |
| django_session               |
+------------------------------+
11 rows in set (0.01 sec)

Regardons maintenant les colonnes de notre modèle Django :

mysql> DESCRIBE articles_blog_article;
+------------------------+--------------+------+-----+---------+----------------+
| Field                  | Type         | Null | Key | Default | Extra          |
+------------------------+--------------+------+-----+---------+----------------+
| id                     | bigint       | NO   | PRI | NULL    | auto_increment |
| title                  | varchar(120) | NO   |     | NULL    |                |
| slug                   | varchar(50)  | YES  | MUL | NULL    |                |
| content                | longtext     | YES  |     | NULL    |                |
| publish_timestamp      | datetime(6)  | YES  |     | NULL    |                |
| user_id                | int          | NO   | MUL | NULL    |                |
+------------------------+--------------+------+-----+---------+----------------+
12 rows in set (0.00 sec)

À part l'écriture d'une configuration de base, Django a fait tout le travail SQL pour nous dans cette base de données MySQL. En fait, la majeure partie de cet exercice n'est pas conçue pour mettre en valeur Django ou Python en tant que remplacement de SQL, mais pour vous rappeler que les abstractions fonctionnent.

L'essor de Python et le coût des frictions

Parlons de la voie de la moindre résistance et de la raison pour laquelle je pense que Python est l'un des meilleurs moyens d'exploiter SQL.

Il est très facile d'écrire, de lire, d'exécuter ET d'expédier Python. Remplacez "Python" par presque n'importe quel autre paradigme de programmation et il est presque impossible de faire la même déclaration. JavaScriptest également un concurrent, mais il est aussi régulièrement confondu avec Java. Je comprends qu'il s'agit de généralisations et que ce n'est pas toujours vrai, mais ce sont des problèmes courants qui se posent lors du développement de votre application.

Je pense que ces généralisations ont tendance à être vraies en raison de la syntaxe anglaise de Python.

Comparons une déclaration SQL à une déclaration Python et Django :

  • SQL : SELECT * from articles_blog_article;
  • Python et Django : items = BlogArticle.objects.all()

Les deux instructions produisent exactement les mêmes données. L'instruction Python , cependant, renvoie une liste d'objets Python (items) que presque tous les développeurs Python , quelle que soit leur expérience, peuvent utiliser. Les résultats SQL bruts devront être convertis avant d'être utilisés dans une application Python .

Descriptions des champs
Si nous examinons de plus près la description de ce champ SQL :

+------------------------+--------------+------+-----+---------+----------------+
| Field                  | Type         | Null | Key | Default | Extra          |
+------------------------+--------------+------+-----+---------+----------------+
| title                  | varchar(120) | NO   |     | NULL    |                |
+------------------------+--------------+------+-----+---------+----------------+

Versus this Django field description :

title = models.CharField(max_length=120)

  • Lequel a le plus de friction ?
  • Lequel est le plus facile à comprendre ?

Qui fournit juste assez d' informations ?

Si vous n'êtes pas un codeur et que vous voyez varchar(120)Que pensez-vous de cela ? Je suis presque sûr que vous pourriez au moins deviner ce qu'il en est. max_length=120 means. Ce qui est intéressant, c'est qu'ils signifient exactement la même chose : limitez ce champ à 120 caractères ou moins.

Ajouter des données à la base de données

Avec Django :

BlogArticle.objects.create(
    title="Hello World",
    content="Coming Soon",
    slug="hello-world",
    publish_timestamp=None,
)

Avec SQL :

INSERT INTO `articles_blog_article` (`user_id`, `title`, `slug`, `content`, `publish_timestamp`) 
VALUES (1, 'Hello World', 'hello-world', 'Coming Soon', NULL);

En ce qui concerne la simplicité et la clarté, je pense que le gagnant est sans aucun doute Django et Python. title = "Hello World" est plus facile que de comprendre ce qui se passe avec la valeur équivalente de la colonne (champ) en SQL. Ne vous y trompez pas, la façon dont cela est écrit en SQL est très efficace lorsque vous savez ce que vous faites.

Ajout de plusieurs lignes
avec Django :

items = [
    BlogArticle(title='Hello Again 0', slug='hello-again-0', content="Coming Soon"),
    BlogArticle(title='Hello Again 1', slug='hello-again-1', content="Coming Soon"),
    BlogArticle(title='Hello Again 2', slug='hello-again-2', content="Coming Soon"),
    BlogArticle(title='Hello Again 3', slug='hello-again-3', content="Coming Soon"),
    BlogArticle(title='Hello Again 4', slug='hello-again-4', content="Coming Soon"),
]
BlogArticle.objects.bulk_create(items)

Avec SQL :

INSERT INTO `articles_blog_article` (`user_id`, `title`, `slug`, `content`, `publish_timestamp`) 
VALUES (1, 'Hello Again 0', 'hello-again-0', 'Coming Soon', NULL),
    (1, 'Hello Again 1', 'hello-again-1', 'Coming Soon', NULL),
    (1, 'Hello Again 2', 'hello-again-2', 'Coming Soon', NULL),
    (1, 'Hello Again 3', 'hello-again-3', 'Coming Soon', NULL),
    (1, 'Hello Again 4', 'hello-again-4', 'Coming Soon', NULL);

Encore une fois, le code Python est plus lisible tandis que le code SQL donne plus d'informations sur les données réelles. Et, encore une fois, Python écrit ce code SQL pour nous en utilisant le code Django ci-dessus. Plutôt sympa, non ?

La raison pour laquelle je me suis plongé dans cette comparaison côte à côte n'est pas de choisir la meilleure façon d'exploiter les bases de données SQL, mais de mettre en évidence la capacité de Pythonà réduire les frais généraux liés à l'apprentissage de l'écriture directe de SQL brut.

Il existe plusieurs paquets Python qui écrivent essentiellement le SQL brut pour vous, en voici quelques-uns :

  • Django
  • Pandas
  • SQLAlchemy
  • Polaires
  • Dask
  • Vaex
  • PythonModule CSV intégré
  • ORM Tortoise
  • Pony ORM
  • SQLObject

Django fait le gros du travail
Les packages de mappage objet-relationnel (communément appelés ORM) sont la sauce secrète qui permet à Python d'exploiter les bases de données SQL. Je considère un ORM comme un intermédiaire qui aide à déplacer les données dans la syntaxe native d'un langage de programmation donné.

Plus tôt dans cet exercice, nous avons commencé à voir comment cela se traduisait pour Django, mais développons cela maintenant.

Supposons que nous ayons des données dans notre base de données, nous pouvons écrire une commande comme celle-ci :

my_post = BlogArticle.objects.first()
Cette instruction interrogera notre base de données, extraira les données, les chargera dans une instance d'un fichier Python Classpuis l'assigner à la variable my_post.

A partir de là, nous pouvons maintenant faire quelque chose comme ceci :

# using a django-managed python shell
# via python manage.py shell
>>> print(my_post.title)
Hello World

Dans ce cas, nous avons utilisé la notation point pour accéder à l'élément title qui a été déclaré dans le champ BlogPost modèle Django de la section précédente. Ce champ correspond à une colonne de notre table de base de données SQL articles_blog_article.

Grâce à l'ORM, nous pouvons le faire :

>>> my_post.title = "some other title"

Dans cet exemple de session shell Python , l'option my_post.title va maintenant toujours être "some other title". La base de données SQL sous-jacente, cependant, reconnaît toujours ces mêmes données en tant que Hello World. La base de données conservera les données originales jusqu'à ce que Python commette finalement (aka .save()) cette modification de données dans la base de données. Si Python ne valide jamais ces données, elles ne seront jamais mises à jour dans la base de données, ce qui fait partie de la magie de l'ORM. Nous pouvons utiliser et changer les données sans affecter les données stockées. Lorsque nous voulons modifier ce qui se passe réellement dans la base de données, nous exécutons :

>>> my_post.title = "some other title again"
>>> my_post.save()

Après l'exécution .save() notre base de données, pour cette ligne particulière, mettra à jour le titre de la colonne pour qu'il corresponde exactement à ce qui est écrit sous la forme d'une chaîne Python ci-dessus. N'oubliez pas que l'élément .save() est spécialement conçue pour effectuer des modifications dans la base de données dans les modèles Django. .save() ne signifie pas grand-chose pour un Python Class sans qu'il n'hérite d'abord d'une classe de modèle Django.

Construire avec Django, MySQL et Linode

C'est l'un des nombreux exemples de la façon dont Django fait le gros du travail à votre place. Si vous êtes intéressé par une approche moderne du déploiement d'applications Django sur Linode, avec une base de données MySQL gérée, des actions GitHub pour CI/CD, Terraform, et Ansible, consultez le contenu suivant, désormais disponible sur Linode :

Pour vous aider à démarrer, le site GitHub Coding for Entrepreneurs propose un référentiel de code correspondant à chaque étape de la série. Bonne chance, et n'oubliez pas de me faire savoir comment les choses se passent via Twitter @JustinMitchel.


Commentaires

Laissez un commentaire

Votre adresse électronique ne sera pas publiée. Les champs obligatoires sont marqués d'un *.