Les critiques des ORM sont à côté de la plaque


En ce moment, y a deux modes. Dire que les cryptomonnaies c’est génial, et dire que les ORM c’est de la merde.

Durant les derniers articles, je pense qu’on vous a assez parlé de crypto, donc on va parler des ORM.

Ou ORMs. Je sais jamais si les acronymes s’accordent.

Rappel: qu’est-ce qu’un ORM ?

Si vous avez lu le titre de l’article et que votre sang n’a fait qu’un tour, vous pouvez passer tout de suite à la partie suivante, puisqu’on va commencer par les révisions.

Un ORM, pour Object-relational Mapping, est une bibliothèque qui permet de décrire son modèle de données, et d’utiliser cette description pour faire le lien entre votre application et une base de données relationnelle. Dans sa forme la plus courante, l’ORM fournit les outils pour générer des requêtes SQL – sans écrire du SQL – et les exécuter, mais présente également les résultats sous forme d’objets du langage dans lequel il est écrit.

Par exemple, en Python, je peux faire de la base de données à la mano (sans ORM):

import sqlite3
 
# Création de la base
with sqlite3.connect('db.sqlite') as conn:
 
    # On se positionne sur la base
    c = conn.cursor()
 
    # Créer la table
    c.execute('''
        CREATE TABLE product (
            name text,
            price real
        )
    ''')
 
    # Insertion de données en base
    c.execute("INSERT INTO product VALUES ('Pizza', 5000)")
    c.execute("INSERT INTO product VALUES ('Love', 150)")
    c.execute("INSERT INTO product VALUES ('Nessie', 3.5)")
 
    # Sauvegarde des changements
    conn.commit()
 
    # Lecture de toute la base:
    for row in c.execute('SELECT * FROM product'):
        print(type(row), ':', *row)

Ce qui va me sortir:

python3 db.py
< class 'tuple' > : Pizza 5000.0
< class 'tuple' > : Love 150.0
< class 'tuple' > : Nessie 3.5

Et voici la même chose avec l’ORM peewee (apres pip install peewee :)):

import peewee as pw
 
# On créé la base
db = pw.SqliteDatabase('product2.db')
 
# Description de la table.
class Product(pw.Model):
 
    name = pw.CharField()
    price = pw.FloatField()
 
    class Meta:
        database = db
 
# Connection et création de la table
db.connect()
db.create_tables([Product])
 
# Insertion de données en base
Product.create(name='Pizza', price=5000)
Product.create(name='Love', price=150)
Product.create(name='Nessie', price=3.5)
 
for p in Product.select():
    print(type(p), ':', p.name, p.price)
 
db.close()

Ce qui sort:

python3 db.py
< class '__main__.Product' > : Pizza 5000.0
< class '__main__.Product' > : Love 150.0
< class '__main__.Product' > : Nessie 3.5

A priori, c’est la même chose, mais avec un style différent. Le premier exemple favorise l’écriture du SQL à la main, fait les requêtes explicitement et récupère les résultats sous forme de tuples. Le second a une surcouche, l’ORM, qui implique que tout est décrit en Python. Le SQL est généré sous le capot, et on récupère les résultats sous forme d’objets Product.

Il existe de nombreux ORM en Python, les plus populaires étant Peewee (pour les petits besoins), SQLAlchemy (pour les gros projets) et l’ORM de Django (ben, si vous utilisez Django ^^). Évidemment le concept des ORM n’est pas particulièrement lié à Python, et on en retrouve dans tous les langages, avec des variations de styles et de fonctionnalités.

Que reproche-t-on aux ORM ?

Avant de répondre aux détracteurs, listons d’abord leurs arguments.

  • C’est un niveau d’indirection de plus, avec de l’implicite et de la magie.
  • L’ORM va générer des requêtes non optimisées, voire lentes.
  • SQL est un excellent DSL spécialisé dans les requêtes. Au lieu d’apprendre une API de plus, autant aller à la source.
  • SQL marche pareil d’un client à l’autre, donc la connaissance est réutilisable, contrairement à celle de son ORM.
  • C’est une béquille pour ne pas apprendre le SQL, et par ailleurs va amener tot ou tard les ignorants à se tirer une balle dans le pied.
  • Les ORMs ne peuvent pas permettre l’usage de toutes les fonctionnalités de sa base de données, et donc limitent la puissance qu’on en tire.
  • Ça ne scale pas. Les gros sites, comme Instagram qui est écrit en Django, on tous finit par virer leurs ORM.

Et vous savez quoi ?

Ils ont raison.

Heu ?

Toutes ces critiques sont parfaitement justifiées.

Sauf qu’elles passent complètement à côté de la problématique.

Les ORM ne servent pas à éviter d’écrire du SQL.

Ça, c’est vaguement un effet de bord.

Ils servent à créer une API unifiée inspectable, une expérience homogène, un point d’entrée unique, un socle de référence explicite et central, pour le modèle de données.

Une fois qu’on a passé pas mal de temps à faire des projets, on note toujours la même chose: certaines parties du logiciel sont réécrites encore et encore. Si un projet commence à parler à une source de données à la main (API, base de données, crawling, fichiers, etc), tôt ou tard, quelqu’un dans l’équipe va commencer à écrire une abstraction. Celle-ci va grossir, et finir par implémenter au bout de nombreux mois, pour l’accès à la base de données, un semi ORM dégueulasse, mal testé / documenté.

Mais, si les requêtes SQL à la main c’est si bien, alors pourquoi ça arrive ?

Simplement parce que tout projet qui grandit a besoin d’une forme de gestion de la complexité. Ca passe par avoir un point, et un seul où sont décrites à quoi ressemblent les données, leurs accès, leurs garanties, leurs contraintes, et leurs validations. Ca passe aussi par permettre aux autres parties du projet d’utiliser automatiquement ces informations pour leur code métier, ainsi que la logique associée.

L’exemple de Django

L’ORM Django n’est pas vraiment le projet Python le plus propre. Il a plein de limitations et bizarreries, et son principal concurrent, SQLAlchemy est probablement une des meilleures libs au monde dans cette spécialité.

Mais !

Il est au coeur de ce qui a fait autant le succès colossal de Django.

Parce que Django est organisé autour de son ORM, il peut proposer:

  • Des validateurs générés automatiquement qui permettent de valider toute saisie de données, et sauvegarder les changements en base de données. Si besoin, il peuvent générer des formulaires HTML afin de proposer une saisie utilisateur automatiquement contrôlée et nettoyée, avec messages d’erreurs pre-traduits.
  • Des vues pour lire, lister, mettre à jour et supprimer les données, générées automatiquement. Y a plus qu’à mettre du HTML autour.
  • Une admin de base de données autogénérée. Un backend gratos et customisable pour votre projet.
  • Une pléthore d’outils pour gérer les données: signals, getters, auto-castage en objet natifs, validation avancées, etc.
  • Des points d’entrées pour étendre la manipulation de ces données de manière générique (fields, managers, etc).
  • De l’outillage pour les migrations.
  • Un worflow d’authentification, d’identification, de session, de cache et de permissions.
  • La normalisation automatique des valeurs: encoding, fuseaux horaires, devises, format de textes et nombres. Et les points d’entrées pour écrire les siens pour plugger ceux de quelqu’un d’autre.

A cela se rajoute le fait que tous les projets Django se ressemblent. Il est très facile de passer d’une équipe à une autre, d’un projet à une autre. La formalisation du schéma devient une documentation, et la seule source de la vérité à propos des données, et pas juste celle de la base. Et qui est commité dans Git. Pour savoir ce que fait un projet Django, il suffit de regarder urls.py, settings.py et models.py, et c’est parti.

Mais ce n’est pas tout. L’ORM ne fait pas que définir un point central inspectable et des outils réutilisables. Il donne aussi une base commune sur laquelle tout le monde peut compter.

Et pour cette raison, l’écosystème Django est très, très riche en modules tierces partis qui se pluggent en 3 coups de cuillère à pot:

La cerise sur le gâteau ? Parce que tout ça utilise l’ORM, tout ça est compatible ensemble. Votre authentification social auth va produire un objet user qui pourra se logger, consulter un dashboard qui contiendra le résultat d’un sondage sur un produit de la boutique.

Et ça marche avec MySQL, Oracle, SQLite ou PosgreSQL, comme l’intégralité du framework, gratos.

Ce n’est pas l’apanage de Django hein, RoR fait pareil.

Maintenant prenez un projet NodeJS. Pour le coup, pas parce que “JS ça pue” mais parce que la culture de l’ORM n’est pas très présente dans cette communauté. Non pas que ça n’existe pas, mais il n’y a pas de Django du monde du Javascript. Même les gros framework type Meteor n’ont rien d’aussi intégré.

Vous allez devoir réapprendre toute la mécanique de gestion de données si vous changez de projet, car ça sera fait différemment à chaque fois. Vous allez devoir former des gens.

Et surtout vous allez devoir réécrire tout ça.

Oh bien sûr, vous aurez une bibliothèque pour chaque chose, mais elle sera écrite différemment. Vous n’aurez pas d’objet User sur qui compter. Votre moyen de traduire le texte ? Pas le même. Vous utilisez Oracle mais l’auteur PostgreSQL ? Pas de bol. Vous voulez générer quelque chose à partir de votre modèle de données ? Ah, pourquoi vous croyez que facebook a créé GraphQL ! Une petite migration ? Vous avez le choix de l’embarras. Bon, maintenant vous allez gérer les dates, et 4 de vos bibliothèques les sérialisent différemment et une utilise l’heure locale au lieu d’UTC.

Évidemment, on sait que votre équipe ne testera pas tout ça, et ne documentera pas tout ça. La suivante non plus.

Donc non, l’ORM, ce n’est pas parce que “mais heu SQL c’est dur”.

C’est parce que ça permet de créer un monde autour.

Objection !

On a des abstractions qui ne sont pas des ORM…

L’important est d’avoir un modèle central, pas un ORM. Mais les ORM font ça particulièrement bien.

Il existe des abstractions (ex: LINQ) qui font un excellent travail pour masquer la source de données. Mais elles ne sont pas un remplacement pour un modèle introspectable central listant nature et contraintes.

Une bonne lib propose les deux.

Par exemple SQLALchemy propose un ORM, mais en vérité l’API de base est fonctionnelle et composable. Pour cette raison, on peut utiliser toutes fonctionnalités avancées de sa base de données avec SQLAlchemy car on a cette alternative à l’ORM à tout moment, et qui est compatible avec l’ORM.

Mais les perfs !

D’abord, on optimise pour les humains. En chemin, on optimise pour la machine. Quand ton ORM arrête de scaler, c’est un BON problème à avoir. Ca veut dire que le projet a atteint un certain succès, et qu’on peut investir dans la séparation avec l’ORM.

De plus, aucune technologie n’est faite pour être utilisée partout, tout le temps, pour tout le projet.

Google a connu ses débuts de succès en Python, et avec sa taille, a réécrit une partie en Java, C puis Go. C’est logique, on ne commence pas avec un langage bas niveau directement, c’est trop lent à écrire. Mais on ne garde pas un langage haut niveau pour tout quand ça monte dans les tours. Enfin les tours… Là on parle de centrifugeuse cosmique hein.

Car gardez en tête que vous n’êtes PAS Google. L’immense majorité des projets deviennent viables, rentables, puis pleins de succès, sans jamais atteindre l’échelle qui amène aux limites de l’ORM.

Quant à l’idée que votre stagiaire peut écrire une boucle avec une requête à chaque step… Il peut tout aussi bien écrire une requête SQL sans se protéger correctement l’injection de code. C’est con un stagiaire, faut le surveiller. C’est le principe, sinon il aurait un CDI.

Mais les fonctionnalités !

Les ORM bien faits n’empêchent pas d’utiliser toutes les fonctionnalités de son système. Et tous permettent d’écrire du SQL à la main si besoin. C’est comme les blocks unsafe de rust: on empêche pas, on isole.

L’idée c’est de garder ça pour le moment où on en a vraiment besoin. SQL est à la base de données ce que l’assembleur est à la machine. On n’écrit pas tout en assembleur de nos jours, ça n’est pas utile.

Root of all evil, tout ça.

Mais on ne change pas de base de données souvent !

L’argument “l’orm supporte plusieurs bases” n’est pas destiné à la migration de données d’un projet existant d’une base de données à une autre.

Pas. Du. Tout.

C’est pas que ça arrive jamais. Ça m’est déjà arrivé 2, 3 de fois.

Mais ce n’est pas le cas courant. Le cas courant c’est la réutilisation du code d’un projet précédent dans un nouveau projet utilisant une base de données différente. C’est la création d’un écosystème de modules qui ne sont pas dépendants de la base de données.

Si vous faites une “app” Django, vous pouvez la publier et elle sera utile pour toutes les bases de données supportées. Et c’est pour ça qu’il y autant d’outils.

Mais on pourrait avoir un modèle central sans ORM !

Oui, mais toutes les formes ne se valent pas.

Par exemple, Doctrine permet d’écrire son modèle dans un fichier YAML, et Hibernate dans un fichier XML.

Au final on écrit son modèle dans un langage moins complet, moins expressif, moins facile à débugger et avec moins de tooling. On perd encore plus en faisant ça qu’en passant de SQL à un ORM, sans autant de gains.

En prime, on peut vouloir de la logique de validation très complexe ou des choses à faire hors validation (signals, génération dynamique de modèle, etc), et là, pouet.

Une alternative, ça serait de se servir d’une lib de pur modèle (ex: l’excellent marshmallow) et de tout dériver de là. Une approche intéressante qui pourrait satisfaire tous les camps, mais que je n’ai jamais vu poussée jusqu’au bout dans aucun framework. Si vous cherchez un projet pour vos week-end :)

Lib VS framework

C’est un peu le vieux débat du découplage VS intégration qu’on retrouve dans la critique des ORM (ou dans vi VS vscode, POO vs fonctionnel, ta femme vs ta mère…).

Et comme d’habitude on retrouve toujours les meilleurs programmeurs du côté de ceux qui veulent le plus de liberté (vive SQL!) parce qu’ils ignorent complètement les problématiques qui vont plus loin que leur fichier de code. Faire fleurir un écosystème, gérer une communauté, favoriser la productivité, facilité l’intégration des membres de ses équipes… Tout ça sont des problématiques moins funs que de faire la requête parfaite avec le tout nouveau champ hyperloglog de PostGres.

Difficile de convaincre des gens qui sont non seulement excellents, mais qui sauront, seuls, être très productifs sans ORM. Surtout quand les gros projets qui atteignent des centaines de millions d’utilisateurs par jour finissent toujours par se séparer de leurs abstractions initiales.

Mais voilà, il ne faut pas perdre de vue que 2 projets sur 3 en informatique, échouent. Quasiment jamais pour des raisons techniques. Généralement la cause est humaine. Et l’ORM est là pour soutenir l’humain en créant un pivot sur lequel il peut compter, quitte à investir plus tard pour s’en passer.

C’est un excellent outil et une très belle réussite de l’informatique moderne. Si on sait l’aborder sans dogmatisme.

41 thoughts on “Les critiques des ORM sont à côté de la plaque

  • OuaisOuais

    Quand ton ORM arrête de scaler, c’est un BON problème à avoir. Ca veut dire que le projet a atteint un certain succès, et qu’on peut investir dans la séparation avec l’ORM.

    Je suis loin de connaitre l’ORM de Django par coeur et je passe sans doute à côté de quelque chose, mais sur un petit projet ecommerce à un moment donné il a fallu que j’importe des fichiers CSV. En utilisant l’ORM c’était long (trop long), parce que je me suis retrouvé à faire beaucoup de chose dans une boucle, forcément. J’ai réécris le bout qui posait problème en déportant une partie de la logique dans une procédure stockée ensuite appelée depuis le code de Django et le soucis était réglé. Oui, ça fait de la dépendance sur Postgre, oui ça peut m’amener à faire double maintenance, mais il est plus important que cet import soit fait dans un temps raisonnable.

    Il est probable que je me serve mal de l’ORM de Django, mais ce que je veux dire c’est qu’on peut avoir -ponctuellement- des problèmes de performance bien avant de s’appeler Google. La performance et la montée en charge sont deux choses différentes, même si elles peuvent être liées.

    Voilà, sinon j’adore Django et oui l’ORM pour autant qu’il soit critiqué permet tout de même de gagner un temps phénoménal, ne serait-ce que de par la quantité d’outils disponibles autour.

  • Thierry

    Salut Sam, ça fait un moment que je lis tes articles même si je ne fais pas vraiment de python.

    Je me suis un peu plus intéressé à cet article parceque j’ai été systématiquement confronté à cette question sur la plupart des projets sur lesquels j’ai bossé.

    Je suis d’accord sur le résultat complexe et inmaintenable qu’on obtient la plupart du temps lorsqu’on s’engage dans le sql.

    L’intérêt principal comme le dit l’acronyme ORM est de gérer plus facilement la complexité du modèle objet et de convertir cette complexité en sql.

    On se retrouve à faire des acrobaties pas possibles et réinventer la roue.

  • MrZok

    Deux petites coquilles repérées :

    – Ca passe pas avoir un point, et un seul -> Ca passe par avoir un point, et un seul

    – Pour le coup, par parce que “JS ça pue” -> Pour le coup, pas parce que “JS ça pue”

  • Tycho

    Merci pour l’article, toujours au top.

    J’aime pas les ORM, à titre personnel. :)

    Je suis curieux et j’aime bien voir comment les choses fonctionnent, découvrir les nouveautés de postgres, ect… Avec un ORM, j’ai l’impression de me gâcher cette possibilité d’apprendre et de comprendre.

    Cela dit, quand je bosse en team, au boulot ou sur de l’open source, je conseille à fond l’utilisation d’ORM, car:

    – les juniors n’ont aucune idée des failles comme les injections sql

    – mine de rien, un ORM permet de faire des join tables plutôt que des n+1 queries comme aurait fait n’importe quel dev débutant, inconscient du danger

    – c’est un premier pas vers du domaine driven développement, parler en objets métiers plus qu’en join de table

    – toutes les autres raisons au dessus.

    Les seuls fois où je déconseille l’orm au profit d’une autre abstraction, c’est quand ça fait double emploi. Par exemple un projet en graphql (serveur node avec apollo) n’a pas besoin d’utiliser sequelize. Graphql fait déjà le mapping avec le système de resolveur, l’optimisation contre les N+1 queries est mieux faite avec dataloader (batching et catching) et de toutes façons, la validation en js c’est pas bien ouf. Quant à l’admin auto, on peut oublier. Au final, pour ce cas d’usage, utiliser knex en query builder, pas directement mais dans des services à part, se prêtait bien au projet qui avait besoin d’utiliser certaines fonctionnalités avancées de postgres (jsonb, fulltextsearch, et stockage de points dans postgis) : rien d’ impossible à l’orm de django mais il est bien au dessus du lot de ce qui se fait en js.

  • dmerej

    Article sympa, mais les ‘signals’ font mal aux yeux. Je pense que tu veux utiliser ‘signaux’ à la place.

  • panda dragon

    “Car gardez en tête que vous n’êtes PAS Google. L’immense majorité des projets deviennent viables, rentables, puis pleins de succès, sans jamais atteindre l’échelle qui amène aux limites de l’ORM.”

    Remarque applicable a l’ensemble des outils/langages d’un projet.

    J’ai l’impression que les gens ne savent plus penser “normal”. Il faut absolument faire dès le départ une architecture qui tienne dans l’éventualité où l’ensemble de l’humanité voudrait y accéder… Et une fois sur deux quand cette architecture est disponible et fiable bah entre temps le monde a continué a avancer et le besoin a changé (et comme par hasard l’architecture magique ne colle pas/plus: c’est le début de la saison des bricolages). YAGNI n’est pas un reflexe.

    On aurait pu penser que les méthodes agiles aurait pu limiter cette dérive mais en fait non car elles rentrent en action une fois que la décision de faire un truc délirant a déjà été prise…

    Sinon dans le SQL vs. ORM je constate que la portabilité du SQL s’étiole dès qu’une requête devient complexe (dans mon cas Oracle vs Sybase) et que les abstractions/ORMs facilitent l’introduction de tests unitaires/mocks.

  • Teocali

    Mais voilà, il ne faut pas perdre de vue que 2 projets sur 3 en informatiques échouent. Quasiment jamais pour des raisons techniques. Généralement la cause est humaine. Et l’ORM est là pour soutenir l’humain en créant un pivot sur lequel il peut compter, quitte à investir plus tard pour s’en passer.

    Putain, merci. Faire comprendre ça aux collègues développeurs, c’est généralement aussi galère que de faire accepter aux managers l’utilisation des dernières technologies…

  • Kearny

    Un super article !

    En revanche une petite précision :

    Ça fait un moment qu’avec Doctrine ou Hibernate on a coutume d’utiliser les annotations au lieux de déclarer les choses dans un fichier séparé. Même si c’est possible comme tu le dis, je n’ai jamais vu de projets faits comme cela.

  • Sam Post author

    @OuaisOuais : les ORMS ont des outils pour le batching. Par exemple https://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.bulk_create. Ca ne sera jamais aussi rapide qu’une procédure stockée, mais ça suffit le plus souvent. Après l’usage d’un ORM ne s’oppose pas à écrire du SQL à la main ponctuellement. C’est sain.

    @Thierry @Tycho @panda dragon @Teocali : :)

    @dmerej: meuf non, c’est le nom du module (https://docs.djangoproject.com/en/1.11/ref/signals/#module-django.db.models.signals)

    @Grain de sel @Kearny @MrZok : merci

  • Matthieu

    C’est une béquille pour ne pas apprendre le SQL, et par ailleurs va amener tot ou tard les ignorants à se tirer une balle dans le pied.

    Je trouve que c’est une très mauvaise idée d’utiliser un ORM sans connaître le fonctionnement de SQL, tout comme c’est une très mauvaise idée de faire du Java sans connaître sa gestion de la mémoire.

    Ça va de pair avec les requêtes lentes : quand on connaît bien son ORM (et qu’il est bien fichu) ET qu’on sait à quoi ressemble le SQL généré ET qu’on comprend ce SQL généré, les requêtes n’ont pas de raison d’être beaucoup plus lentes (à part dans quelques rares cas).

    Quelqu’un qui fait plein de MonModel(**kwargs).save() au lieu d’un MonModel.objects.bulk_insert() aurait fait l’équivalent en SQL et aurait eu le même problème de performance.

  • Réchèr

    C’est pas grave de se tirer une balle dans le pied, puisque justement on a une béquille !

    (Désolé, commentaire inutile, mais j’ai pas pu résister).

    Et sinon il y a un “à” qui n’a rien à faire là dans cette phrase :

    ” Celle-ci va grossir, et finir par implémenter au bout de nombreux mois, pour l’accès à la base de données, à un semi ORM dégueulasse, mal testé / documenté.”

  • Raoullevert

    Toutes les technos ont des avantages et des inconvénients. Et tu résumes parfaitement la situation. Pour la rapidité, j’utilise souvent redis comme cache …

  • mothsart

    Dans les langages compilés (Linq en C# et Diesel pour Rust par exemple) , l’avantage d’un “bon” ORM (c’est paest également d’avoir la garanti que la requète est bien formé si ça compile

  • mothsart

    Un gros avantage que je vois également sur les langages compilés : les “bon” ORM (Diesel pour Rust, Linq pour C# mais pas NHibernate) permettent de garantir qu’une requète est bien formé rien qu’à la compilation.

  • OuaisOuais

    @Sam: merci pour la doc, je vais creuser ça. Je ne suis pas certain qu’un bulk_create aurait changé les choses car pour mon cas particulier, le problème venait du fait que je devais calculer des choses en boucle avec des données venant de la DB (et donc va et vient permanent lecture/écriture entre Postgre et Python qui finit par coûter cher en temps). C’est le seul endroit où j’ai eu besoin de reprendre la main en SQL, le reste n’a pas posé de problème.

  • Yoko

    Salut !

    Merci pour l’article :)

    Je ne connais pas l’écosystème python mais en terme de performance hibernate apporte un cache de premier niveau qui a sauvé pas mal de projets que j’ai vu qui ne se rendent pas forcément compte du nombre de requêtes qui seraient générée sans.

    Ce dont tu parle me semble surtout discriminer 2 approches distinctes (bien que des fois implémentées dans une même lib). L’utilisation de manière “opiniated” ou non de sa lib. Il existe des ORM très orientées qui vont te pousser à suivre un ensemble de bonnes pratiques et d’autres qui vont être de « simples » surcouches au SGBD(R). Les premiers sont très bien. Si vous avez eu l’occasion de regarder ce que peu faire Spring Data avec les repository c’est vraiment simple sans pour autant rendre l’utilisation magique (on voit où est fait quoi et comment le personnalisé), mais il est bon d’avoir conscience des bonnes pratiques en question pour effectivement les suivre d’une part et d’autre part pour savoir s’il s’agit des bonnes pratiques que l’on souhaite appliquer sur notre projet. C’est un choix à faire au début.

    Pour ce qui est de la gestion des changements ce qui est important c’est de partir sur des DAO quoi qu’il arrive.

    J’ai tout de même rencontré des limitations très contraignantes avec l’utilisation d’ORM non pas sur le requêtage mais sur la modélisation. Il y a des modélisations qui sont à minima lourdes à reproduire avec un ORM (des cas de clefs primaires qui sont des compositions de clefs étrangères par exemple).

    Bonne soirée

  • Lowteast

    Salut,

    Article très intéressant,

    Peut on considérer une api entre la bdd et l’appli comme une ORM?

    Cdlt

  • Lowteast

    Peux tu expliquer un peu plus ta réponse ? J’ai trouvé ton point de vue assez intéressant et je souhaiterais suivre cette idée d’ORM via mon API.

  • Sam Post author

    O => il faut que ce soit un object

    R => il faut une notion de relation

    M => Il faut un lien entre les deux concepts

  • Cym13

    Un point qui n’a pas été mentionné (car moins central) est l’impact en terme de sécurité. On trouve encore beaucoup d’injections SQL dans de nouveaux projets. Il est rare que toutes les requêtes soient impactées (preuve que l’idée d’échapper est comprise à un niveau basique), mais trop souvent quelques requêtes passent tout de même.

    La raison est simple : les programmeurs réfléchissent. Ils se posent la question “Est-il nécessaire d’échapper ici ? Est-ce que ça a un risque d’être compromis ?”. Bien souvent la réponse est non, ça n’est pas nécessaire car les données viennent effectivement de processus interne etc. Mais ça ne veut pas dire qu’il faut ne pas échapper. Se poser la question c’est introduire une chance de se tromper et d’expérience par rapport aux nombreux audits applicatifs que j’ai pu réaliser c’est une chance qui se concrétise souvent. Bien sûr on peut juste dire “ne posez pas de question, échappez” mais en pratique ça ne semble pas être bien respecté.

    Un bon ORM (un qui n’introduit pas ses propres bugs) a cet avantage qu’il n’y a qu’un seul langage, pas de DSL. C’est capital car toute injection intervient à l’interface entre deux langages. Utiliser un ORM permet d’éviter ce risque presque entièrement (il y a toujours des cas particuliers mais dans l’ensemble c’est mieux). Un bon ORM évite de se poser la question. Un bon ORM évite d’introduire une chance d’erreur.

    (Et augmente la surface d’attaque en ayant possiblement ses propres bugs… tout est compromis.)

  • elnazi

    Les ORM c’est pour la nouvelle génération d’informaticiens, nuls en maths, nul en algo et qui ne savent pas faire de la requête SQL ;) mais qui me cassent les couilles avec leurs JS en carton ! L’informatique c’est comme le reste, il ne reste que des usurpateurs.

  • osef

    Tout à fait d’accord @elnazi retournons au code C et SQL pur, des languages pour des informaticiens à grosse bite. Marre de toute ces fiottes qui ne savent plus coder qu’à coup de copié collé de stackoverflow.

  • elnazi

    @osef

    Bein voilà, enfin un gars qui a la même grosse bite que moi…bienvenue copain ;)de la bite !

    Attention tout le monde, on est désormais 2 à avoir une grosse bite !

    Sinon ça vous fait quoi les autres d’avoir des petites bites de frameworker ? :)=

  • Mika

    @elnazi @osef Du coup vous attendez quoi pour aller vous lecher la nouille mutuellement dans les chiottes ? ^^

    Bien d’accord pour le JS mais si seulement il y avait autre chose…

  • Toto

    @les grosses bites : passez à l’assembleur pour faire votre site web ça c’est pas pour les pédales, vous ferez des fonctions, des libs, et des frameworks (si vous l’avez assez grosse) pour vous simplifier la vie et quand vous aurez fini, ben vous aurez une petite bite et en plus faudra refaire parce qu’il y aura des nouveaux procs et que ce que vous avez fait ben tout le monde s’en branle désormais…

    Signé une petite bite qui aimerait être grosse et se faire lécher (qui aime bien ce site et doute de la pertinence de ce commentaire).

    @Sam et Max : merci de reconforter les petites bites débutantes dans leurs choix, qui s’arrachent les cheveux avec les : “no change detected” qui perdent un temps fou a comprendre cette …. qui est censé faire gagner du temps.

  • jeaniv

    A quand un article de sam et max sur les relation sexuelles par commentaire interposés ?!

    • Sam Post author

      Jamais. Le sexe sans sexe, c’est comme une omelette aux lardons végétalienne.

  • bobx

    «Le sexe sans sexe, c’est comme une omelette aux lardons végétalienne.»

    Je ne suis pas concerné, je suis vagintarien.

  • Sam Post author

    “Les ORMs sont une annerie. Voici ma solution, qui est un ORM en moins bien”

  • benbout

    Tu sembles avoir oublié qu’il existe une troisième mode récurrente : dire que pytnon c’est de la merde.

  • Michel

    Bonjour !

    Merci beaucoup pour ces articles merveilleux;

    J’espère que vous allez bien…

    Je voulais demander : Est-ce que c’est possible d’utiliser l’ORM de django dans un autres projet comme une application d’interface graphique avec PyQT par exemple ?

    Sinon quelques suggestions…

    Merci d’avance

  • Sam Post author

    Oui. Il faut quand même installer tout Django, mais c’est possible. Mets les requêtes dans des threads pour ne pas bloquer l’ui.

  • saïd

    Hello guys,

    Je préfère implementer les abstractions cote base de données, comme les functions/vues/contraites car j’ai besoin de:

    performance, fiabilité et interopabilité (nous avons des backend en python/perl/php).

    L’avantage est qu’il n’y a pas besoin de re-creer la logique a chaque fois.

    Ensuite je mappe avec SQLAlchemy CORE pour avoir un ensemble unifier dans python.

  • Sam Post author

    Tes backend devraient taper dans une API plutot que directement sur la base de données. L’avantage de l’API est qu’elle est indépendant du traitement qu’il y a derrière. Donc elle peut faire un appel à la base de données, une récupération depuis un cache, un appel à un service externe, un calcul, etc.

Comments are closed.

Des questions Python sans rapport avec l'article ? Posez-les sur IndexError.