web-dev-qa-db-fra.com

Python prend-il en charge les instructions préparées par MySQL?

J'ai déjà travaillé sur un projet PHP précédemment, où des instructions préparées accéléraient de 20% les requêtes SELECT.

Je me demande si cela fonctionne sur Python? Je n'arrive pas à trouver quoi que ce soit qui dit spécifiquement qu'il fait ou ne fait PAS.

46
rubayeet

Réponse directe, non.

(réponse de Joshperry } est une bonne explication de ce qu'il fait à la place.

De eugene y répond à une question similaire ,

Vérifiez MySQLdb Commentaires sur le paquet :

Le "paramétrage" est fait dans MySQLdb en échappant des chaînes, puis en les interpolant à l'aveuglette dans la requête, au lieu d'utiliser le API MYSQL_STMT. En conséquence, les chaînes unicode doivent passer par deux représentations intermédiaires (chaîne codée, chaîne codée échappée) avant qu'ils ne soient reçus par la base de données.

Donc, la réponse est: non.

12
James McMahon

La plupart des langages fournissent un moyen de faire des instructions paramétrées génériques, Python n’est pas différent. Lorsqu'une requête paramétrée est utilisée, les bases de données prenant en charge la préparation des instructions le feront automatiquement.

En python, une requête paramétrée ressemble à ceci:

cursor.execute("SELECT FROM tablename WHERE fieldname = %s", [value])

Le style spécifique de paramétrage peut varier en fonction du pilote, vous pouvez importer votre module de base de données puis créer un print yourmodule.paramstyle.

De PEP-249 :

paramstyle

       String constant stating the type of parameter marker
       formatting expected by the interface. Possible values are
       [2]:

           'qmark'         Question mark style, 
                           e.g. '...WHERE name=?'
           'numeric'       Numeric, positional style, 
                           e.g. '...WHERE name=:1'
           'named'         Named style, 
                           e.g. '...WHERE name=:name'
           'format'        ANSI C printf format codes, 
                           e.g. '...WHERE name=%s'
           'pyformat'      Python extended format codes, 
                           e.g. '...WHERE name=%(name)s'
58
joshperry

Après un rapide coup d'œil à travers la méthode execute () d'un objet Cursor d'un paquet MySQLdb (une sorte de paquet de facto pour l'intégration avec mysql, je suppose), il semble que (du moins par défaut), il ne fait que l'interpolation et citant et non la requête paramétrée réelle:

if args is not None:
    query = query % db.literal(args)

Si ce n'est pas une interpolation de chaîne, alors qu'est-ce que c'est?

En cas d'exécution, il essaie en réalité d'exécuter l'insertion/remplacement en tant qu'instruction unique, par opposition à une exécution en boucle. C'est à peu près tout, pas de magie, semble-t-il. Du moins pas dans son comportement par défaut.

EDIT: Oh, je viens de me rendre compte que l’opérateur modulo pourrait être écrasé, mais j’ai eu l’impression de tricher et d’attraper la source. Nous n'avons pas trouvé de variable mod nulle part, cependant.

10
shylent

Pour ceux qui essaient juste de comprendre cela, OUI, vous pouvez utiliser des instructions préparées avec Python et MySQL. Utilisez simplement MySQL Connector/Python depuis MySQL et instanciez le curseur de droite:

https://dev.mysql.com/doc/connector-python/en/index.html

https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursorprepared.html

5
fromvega

L'utilisation de l'interface SQL, comme suggéré par Amit, peut fonctionner si vous êtes uniquement préoccupé par les performances. Cependant, vous perdez alors la protection contre l'injection SQL qu'un support Python natif pour les instructions préparées pourrait apporter. Python 3 contient des modules qui fournissent un support d’instruction préparé pour PostgreSQL. Pour MySQL, "oursql" semble fournir un vrai support pour les instructions préparées (non falsifié comme dans les autres modules).

5
user304386

Non directement lié, mais cette réponse à une autre question de SO inclut les détails de la syntaxe des requêtes 'modèles'. Je dirais que l'échappement automatique serait leur caractéristique la plus importante ...

En ce qui concerne les performances, notez la méthode executemany sur les objets curseur. Il regroupe un certain nombre de requêtes et les exécute en une fois, ce qui conduit à de meilleures performances.

1
Michał Marczyk

Il y a une solution!

Vous pouvez les utiliser si vous les mettez dans une procédure stockée sur le serveur et appelez-les comme ça depuis python ... 

cursor.callproc(Procedurename, args)

Voici un joli petit tutoriel sur les procédures stockées dans mysql et python.

http://www.mysqltutorial.org/calling-mysql-stored-procedures-python/

0
whoopididoo