Python MySQL参数化查询
我很难用MySQLdb模块将信息插入到我的数据库中。 我需要插入6个variables到表中。
cursor.execute (""" INSERT INTO Songs (SongName, SongArtist, SongAlbum, SongGenre, SongLength, SongLocation) VALUES (var1, var2, var3, var4, var5, var6) """)
有人可以帮我在这里的语法?
注意为SQL查询使用string插值,因为它不会正确地转义input参数,并且会使您的应用程序开放到SQL注入漏洞。 这种差异可能看起来微不足道,但实际上却是巨大的 。
不正确(有安全问题)
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))
它增加了混淆,用于绑定SQL语句中的参数的修饰符在不同的DB API实现之间有所不同,并且mysql客户端库使用printf
样式语法而不是更常用的“?” 标记(由例如python-sqlite
)。
你有几个选项可用。 你会希望得到python的stringiterpolation舒适。 这是一个术语,当你想知道这样的东西时,你可能会在未来寻找更多的成功。
更好的查询:
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)
考虑到你可能已经把所有的数据都放在一个对象或者字典中了,第二种格式会更适合你。 当你不得不在一年内回来并更新这个方法时,它也不得不在string中计数“%s”的外观:)
链接的文档给出以下示例:
cursor.execute (""" UPDATE animal SET name = %s WHERE name = %s """, ("snake", "turtle")) print "Number of rows updated: %d" % cursor.rowcount
所以你只需要适应你自己的代码 – 例如:
cursor.execute (""" INSERT INTO Songs (SongName, SongArtist, SongAlbum, SongGenre, SongLength, SongLocation) VALUES (%s, %s, %s, %s, %s, %s) """, (var1, var2, var3, var4, var5, var6))
(如果SongLength是数字,则可能需要使用%d而不是%s)。
实际上,即使你的variables(SongLength)是数字的,你仍然必须用%s格式化它,以正确地绑定参数。 如果您尝试使用%d,则会出现错误。 这里是这个链接http://mysql-python.sourceforge.net/MySQLdb.html的一小段摘录:;
要执行查询,您首先需要一个游标,然后您可以对其执行查询:
c=db.cursor() max_price=5 c.execute("""SELECT spam, eggs, sausage FROM breakfast WHERE price < %s""", (max_price,))
在这个例子中,max_price = 5为什么在string中使用%s? 因为MySQLdb会将其转换为SQL字面值,即string“5”。 当它完成时,查询实际上会说:“… WHERE价格<5”。
作为所选答案的替代scheme,以及与Marcel's相同的安全语义,下面是使用Python字典指定值的一种紧凑方法。 它具有在添加或删除要插入的列时易于修改的好处:
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()
其中meta是包含要插入的值的字典。 更新可以用同样的方法完成:
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()