J'ai du mal à utiliser le module MySQLdb pour insérer des informations dans ma base de données. Je dois insérer 6 variables dans le tableau.
cursor.execute ("""
INSERT INTO Songs (SongName, SongArtist, SongAlbum, SongGenre, SongLength, SongLocation)
VALUES
(var1, var2, var3, var4, var5, var6)
""")
Quelqu'un peut-il m'aider avec la syntaxe ici?
Méfiez-vous de l'interpolation de chaîne pour les requêtes SQL, car elle n'échappera pas correctement aux paramètres d'entrée et laissera votre application ouverte aux vulnérabilités d'injection SQL. La différence peut sembler triviale, mais en réalité, elle est énorme .
c.execute("SELECT * FROM foo WHERE bar = %s AND baz = %s" % (param1, param2))
c.execute("SELECT * FROM foo WHERE bar = %s AND baz = %s", (param1, param2))
Cela ajoute à la confusion que les modificateurs utilisés pour lier les paramètres dans une instruction SQL varient selon les implémentations de l'API de base de données et que la bibliothèque client mysql utilise la syntaxe de style printf
au lieu du plus communément accepté '?' marqueur (utilisé par exemple. python-sqlite
).
Vous avez quelques options disponibles. Vous voudrez vous familiariser avec la chaîne iterpolation de python. C’est un terme que vous aurez peut-être plus de succès à rechercher à l’avenir lorsque vous souhaitez connaître des informations de ce type.
Mieux pour les requêtes:
some_dictionary_with_the_data = {
'name': 'awesome song',
'artist': 'some band',
etc...
}
cursor.execute ("""
INSERT INTO Songs (SongName, SongArtist, SongAlbum, SongGenre, SongLength, SongLocation)
VALUES
(%(name)s, %(artist)s, %(album)s, %(genre)s, %(length)s, %(location)s)
""", some_dictionary_with_the_data)
Étant donné que vous avez probablement déjà toutes vos données dans un objet ou un dictionnaire, le second format vous conviendra mieux. De plus, il est nul de devoir compter "% s" dans une chaîne lorsque vous devez revenir et mettre à jour cette méthode dans un an :)
Les documents liés donnent l'exemple suivant:
cursor.execute ("""
UPDATE animal SET name = %s
WHERE name = %s
""", ("snake", "turtle"))
print "Number of rows updated: %d" % cursor.rowcount
Il vous suffit donc d’adapter cela à votre propre code - exemple:
cursor.execute ("""
INSERT INTO Songs (SongName, SongArtist, SongAlbum, SongGenre, SongLength, SongLocation)
VALUES
(%s, %s, %s, %s, %s, %s)
""", (var1, var2, var3, var4, var5, var6))
(Si SongLength est numérique, vous devrez peut-être utiliser% d au lieu de% s).
En guise d'alternative à la réponse choisie et avec la même sémantique sûre que celle de Marcel, voici un moyen compact d'utiliser un dictionnaire Python pour spécifier les valeurs. Il a l'avantage d'être facile à modifier lorsque vous ajoutez ou supprimez des colonnes à insérer:
meta_cols=('SongName','SongArtist','SongAlbum','SongGenre')
insert='insert into Songs ({0}) values ({1})'.
.format(','.join(meta_cols), ','.join( ['%s']*len(meta_cols) ))
args = [ meta[i] for i in meta_cols ]
cursor=db.cursor()
cursor.execute(insert,args)
db.commit()
Où meta est le dictionnaire contenant les valeurs à insérer. La mise à jour peut se faire de la même manière:
meta_cols=('SongName','SongArtist','SongAlbum','SongGenre')
update='update Songs set {0} where id=%s'.
.format(','.join([ '{0}=%s'.format(c) for c in meta_cols ]))
args = [ meta[i] for i in meta_cols ]
args.append( songid )
cursor=db.cursor()
cursor.execute(update,args)
db.commit()
En réalité, même si votre variable (SongLength) est numérique, vous devrez quand même la formater avec% s pour lier correctement le paramètre. Si vous essayez d'utiliser% d, vous obtiendrez une erreur. Voici un petit extrait de ce lien http://mysql-python.sourceforge.net/MySQLdb.html :
Pour effectuer une requête, vous devez d'abord disposer d'un curseur, puis vous pouvez y exécuter des requêtes:
c=db.cursor()
max_price=5
c.execute("""SELECT spam, eggs, sausage FROM breakfast
WHERE price < %s""", (max_price,))
Dans cet exemple, max_price = 5 Pourquoi, alors, utiliser% s dans la chaîne? Parce que MySQLdb le convertira en une valeur littérale SQL, qui correspond à la chaîne '5'. Quand ce sera terminé, la requête indiquera en fait "... WHERE price <5".
La première solution fonctionne bien. Je veux ajouter un petit détail ici. Assurez-vous que la variable que vous essayez de remplacer/mettre à jour doit être de type str. Mon type mysql est décimal, mais je devais définir le paramètre variable comme str pour pouvoir exécuter la requête.
temp = "100"
myCursor.execute("UPDATE testDB.UPS SET netAmount = %s WHERE auditSysNum = '42452'",(temp,))
myCursor.execute(var)
Voici une autre façon de le faire. C'est documenté sur le site officiel de MySQL . https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-execute.html
Dans l’esprit, il utilise le même mécanisme que celui de @Trey Stout. Cependant, je trouve celui-ci plus joli et plus lisible.
insert_stmt = (
"INSERT INTO employees (emp_no, first_name, last_name, hire_date) "
"VALUES (%s, %s, %s, %s)"
)
data = (2, 'Jane', 'Doe', datetime.date(2012, 3, 23))
cursor.execute(insert_stmt, data)
Et pour mieux illustrer le besoin de variables:
NB: notez l'évasion en cours.
employee_id = 2
first_name = "Jane"
last_name = "Doe"
insert_stmt = (
"INSERT INTO employees (emp_no, first_name, last_name, hire_date) "
"VALUES (%s, %s, %s, %s)"
)
data = (employee_id, conn.escape_string(first_name), conn.escape_string(last_name), datetime.date(2012, 3, 23))
cursor.execute(insert_stmt, data)