我在使用MySQLdb模块向数据库插入信息方面遇到了麻烦。我需要将6个变量插入到表中。
cursor.execute ("""
INSERT INTO Songs (SongName, SongArtist, SongAlbum, SongGenre, SongLength, SongLocation)
VALUES
(var1, var2, var3, var4, var5, var6)
""")
有人能帮我看一下这里的语法吗?
我在使用MySQLdb模块向数据库插入信息方面遇到了麻烦。我需要将6个变量插入到表中。
cursor.execute ("""
INSERT INTO Songs (SongName, SongArtist, SongAlbum, SongGenre, SongLength, SongLocation)
VALUES
(var1, var2, var3, var4, var5, var6)
""")
有人能帮我看一下这里的语法吗?
不要使用字符串插值来构建SQL查询,因为它不能正确转义输入参数,并会使你的应用程序容易受到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语句中用于绑定参数的修饰符在不同的数据库API实现中有所不同,而且mysql客户端库使用的是printf
风格的语法,而不是更常见的“?”标记(例如python-sqlite
中使用的方式),这增加了混淆。
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)
考虑到你可能已经把所有的数据都放在对象或字典中了,第二种格式会更适合你。而且当你在一年后需要回来更新这个方法时,统计字符串中"%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))
< p >(如果 SongLength 是数字,您可能需要使用 %d 而不是 %s)。< /p >实际上,即使您的变量(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,))
作为选择答案的替代方案,并具有Marcel所选择的安全语义,以下是一种使用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()
temp = "100"
myCursor.execute("UPDATE testDB.UPS SET netAmount = %s WHERE auditSysNum = '42452'",(temp,))
myCursor.execute(var)
这里有另一种方法可以实现。它在MySQL官方网站上有详细的文档。 https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-execute.html
从本质上讲,它使用了与@Trey Stout答案相同的机制。但是,我发现这个更漂亮、更易读。
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)
为了更好地说明变量的必要性:
注意进行的转义。
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)
printf
风格的%s
标记感到非常困惑,我有点害怕自己写出了易受攻击的查询语句。谢谢你消除了我的疑虑! :) - Darragh Enrightc.execute("SELECT * FROM foo WHERE bar = %s", (param1,))
。 - Marius Lian