Comment citer une valeur de chaîne de façon explicite (Python DB API/Psycopg2)
Pour certaines raisons, je souhaiterais faire un explicite, citant une chaîne de valeur (de devenir une partie de construit la requête SQL), au lieu d'attendre implicite devis effectué par cursor.execute
méthode que sur le contenu de son deuxième paramètre.
Par "implicite citation" je veux dire:
value = "Unsafe string"
query = "SELECT * FROM some_table WHERE some_char_field = %s;"
cursor.execute( query, (value,) ) # value will be correctly quoted
Je préfère quelque chose comme ça:
value = "Unsafe string"
query = "SELECT * FROM some_table WHERE some_char_field = %s;" % \
READY_TO_USE_QUOTING_FUNCTION(value)
cursor.execute( query ) # value will be correctly quoted, too
Est si bas niveau READY_TO_USE_QUOTING_FUNCTION
prévu par Python DB spécification de l'API (je ne pouvais pas trouver une telle fonctionnalité dans PEP 249 document). Si non, peut-être Psycopg2 fournit une telle fonction? Si non, peut-être que Django fournit une telle fonction? Je préfère ne pas écrire une telle fonction de moi-même...
- Je vous suggère de chercher dans SQLAlchemy du générateur SQL API, même si vous n'êtes pas intéressé par l'ORM composants; cela vous permettra de lier les valeurs, tout en conservant la flexibilité.
- Quelque chose comme
db_cur.execute('''UPDATE test_table SET field_1="%s" WHERE field_2="%s"''' % (data, condition))
Note le triple des apostrophes et des guillemets autour de%s
Vous devez vous connecter pour publier un commentaire.
Ok, donc j'étais curieux et je suis allé regardé la source de psycopg2. S'avère que je n'ai pas eu à aller plus loin que le dossier exemples 🙂
Et oui, c'est psycopg2 spécifiques. En gros, si vous voulez juste pour citer une chaîne de caractères, vous feriez ceci:
Mais ce que vous voulez probablement faire est d'écrire et d'enregistrer votre propre adaptateur;
Dans le dossier exemples de psycopg2 vous trouverez le fichier 'myfirstrecipe.py', il est un exemple de la manière de voter, et de citer un type spécifique d'une manière spéciale.
Si vous avez des objets pour les trucs que vous voulez faire, vous pouvez simplement créer un adaptateur qui est conforme à la " IPsycopgSQLQuote protocole (voir pydocs pour la myfirstrecipe.py-exemple...en fait c'est la seule référence que je peux trouver à ce nom) qui cite votre objet, puis l'enregistrer comme:
Aussi, les autres exemples sont intéressants; esp. 'dialtone.py' et 'simple.py'.
Je suppose que vous êtes à la recherche pour le mogrify fonction.
Exemple:
Vous devriez essayer d'éviter de faire votre propre citant. Non seulement il sera DB spécifiques comme les gens l'ont souligné, mais les défauts en citant la source de bogues de l'injection SQL.
Si vous ne voulez pas passer des requêtes et des valeurs séparément, puis de les transmettre autour d'une liste de paramètres:
(J'ai probablement la syntaxe de curseur.exécuter mal) Le point ici est que juste parce que le curseur.exécuter prend un certain nombre d'arguments, cela ne signifie pas que vous avez à les traiter séparément. Vous pouvez les traiter comme une seule liste.
Ce sera la base de données dépendantes (iirc, mysql permet
\
comme un caractère d'échappement, tandis que quelque chose comme oracle attend citations d'être doublé:'my '' quoted string'
).Quelqu'un me corrige si je me trompe, mais le double citant méthode est la méthode standard.
Il peut être intéressant de regarder ce que les autres db abstraction de bibliothèques (sqlalchemy, cx_Oracle, sqlite, etc).
J'ai demander - pourquoi voulez-vous inline les valeurs au lieu de les lier?
Je ne pense pas que vous donner suffisamment de raisonnement derrière votre évitement pour ce faire de La bonne Façon. S'il vous plaît, l'utilisation de l'APi qu'il est conçu et ne pas essayer si dur pour faire de votre code moins lisible pour le gars à côté, et de plus en plus fragile.
Cela va être DB dépendante. Dans le cas de MySQLdb, par exemple, la
connection
classe a unliteral
méthode qui vous permet de convertir la valeur de la bonne échappé à la représentation pour le passage à MySQL (c'est ce quecursor.execute
utilise).J'imagine Postgres a quelque chose de similaire, mais je ne pense pas qu'il existe une fonction pour échapper à valeurs dans le cadre de la DB API spec 2.0.
Votre extrait de code serait juste comme ça, selon psycopg extension docs
La
getquoted
fonction renvoie lavalue
comme une cité et s'est échappé de la chaîne, de sorte que vous pouvez aussi aller:"SELECT * FROM some_table WHERE some_char_field = " + adapt(value).getquoted()
.PyPika dans une autre bonne option pour la construction d'instructions SQL. Exemple d'utilisation (basé sur un exemple sur la page d'accueil du projet):
Si vous utilisez django, vous pourriez vouloir utiliser la citation d'une fonction qui est automatiquement adapté à la configuration actuelle de SGBD :
quote_name
enferme chaîne de résultat avec des guillemets doubles. PostgreSQL (8.2.5) ne le permet pas en tant que chaîne de caractères délimiteurs (il semble qu'ils sont utilisés pour des identificateurs entre guillemets). À l'aide de la fonction fournie par django serait le mieux pour moi, malheureusement, je ne vois pas de fonction propre en db de la fpo.pouvez faire le travail de simple citant qui travaille au moins avec MySQL. Ce dont nous avons vraiment besoin est de curseur.fonction format() qui fonctionne comme curseur.execute (), sauf qu'elle serait de retour de la requête au lieu de l'exécuter. Il ya des moments où vous ne voulez pas que la requête à exécuter tout à fait encore - e.g vous pouvez connecter d'abord, ou l'imprimer pour le débogage avant d'aller de l'avant avec elle.
'...'
littéraux, ce qui est totalement faux. Pour postgresql non standard de laE'...'
style de littéraux, qui est proche de chaînes C, c'est proche, mais toujours dangereux. Lors de la sérialisation/s'échapper, toujours utiliser des outils conçus pour la cible de syntaxe! Par exemple, il avait juridiques pourre.escape
à utiliser[.]
pour échapper à.
, qui travaille dans les expressions régulières, mais totalement pas ce que vous voulez dans SQL.