web-dev-qa-db-fra.com

Comment utiliser les variables dans une instruction SQL en Python?

Ok, donc je ne suis pas aussi expérimenté en Python.

J'ai le code suivant Python:

cursor.execute("INSERT INTO table VALUES var1, var2, var3,")

var1 est un entier, var2 & var3 sont des chaînes.

Comment puis-je écrire les noms de variables sans python les inclure dans le texte de la requête?

78
user111606
cursor.execute("INSERT INTO table VALUES (%s, %s, %s)", (var1, var2, var3))

Notez que les paramètres sont passés en tant que tuple.

L'API de base de données effectue correctement l'échappement et la citation des variables. Veillez à ne pas utiliser l'opérateur de formatage de chaîne (%), parce que

  1. il ne fait aucune fuite ou citation.
  2. il est sujet aux attaques incontrôlées sur le format de chaîne, par exemple. injection SQL .
81
Ayman Hourieh

Différentes implémentations de la Python DB-API sont autorisées à utiliser différents espaces réservés. Vous devez donc déterminer lequel vous utilisez - cela pourrait être (par exemple avec MySQLdb):

cursor.execute("INSERT INTO table VALUES (%s, %s, %s)", (var1, var2, var3))

ou (par exemple avec sqlite3 à partir de la Python)):

cursor.execute("INSERT INTO table VALUES (?, ?, ?)", (var1, var2, var3))

ou d'autres encore (après VALUES vous pourriez avoir (:1, :2, :3), ou "styles nommés" (:fee, :fie, :fo) ou (%(fee)s, %(fie)s, %(fo)s) où vous passez un dict au lieu d’une carte comme second argument de execute). Vérifiez la constante de chaîne paramstyle dans le module d'API de base de données que vous utilisez et recherchez le paramètre à la place de http://www.python.org/dev/peps/pep-0249/ pour voir quels sont tous les styles de passage de paramètres!

59
Alex Martelli

Plusieurs façons. NE PAS utiliser le plus évident (%s avec %) en code réel, il est ouvert à attaques .

Ici copier-coller de pydoc de sqlite:

# Never do this -- insecure!
symbol = 'RHAT'
c.execute("SELECT * FROM stocks WHERE symbol = '%s'" % symbol)

# Do this instead
t = ('RHAT',)
c.execute('SELECT * FROM stocks WHERE symbol=?', t)
print c.fetchone()

# Larger example that inserts many records at a time
purchases = [('2006-03-28', 'BUY', 'IBM', 1000, 45.00),
             ('2006-04-05', 'BUY', 'MSFT', 1000, 72.00),
             ('2006-04-06', 'SELL', 'IBM', 500, 53.00),
            ]
c.executemany('INSERT INTO stocks VALUES (?,?,?,?,?)', purchases)

Plusieurs exemples si vous avez besoin de:

# Multiple values single statement/execution
c.execute('SELECT * FROM stocks WHERE symbol=? OR symbol=?', ('RHAT', 'MSO'))
print c.fetchall()
c.execute('SELECT * FROM stocks WHERE symbol IN (?, ?)', ('RHAT', 'MSO'))
print c.fetchall()
# This also works, though ones above are better as a habit as it's inline with syntax of executemany().. but your choice.
c.execute('SELECT * FROM stocks WHERE symbol=? OR symbol=?', 'RHAT', 'MSO')
print c.fetchall()
# Insert a single item
c.execute('INSERT INTO stocks VALUES (?,?,?,?,?)', ('2006-03-28', 'BUY', 'IBM', 1000, 45.00))
35
Kashyap

http://www.amk.ca/python/writing/DB-API.html

Faites attention lorsque vous ajoutez simplement des valeurs de variables à vos instructions: imaginez un utilisateur qui se nomme lui-même ';DROP TABLE Users;' _ C'est pourquoi vous devez utiliser l'échappement SQL, ce que Python fournit pour vous lorsque vous utilisez le curseur.exécute de manière décente. Exemple dans l'URL:

cursor.execute("insert into Attendees values (?, ?, ?)", (name,
seminar, paid) )
20
Numlock