我很难使用MySQLdb模块将信息插入到我的数据库中。我需要在表中插入6个变量。
cursor.execute ("""
INSERT INTO Songs (SongName, SongArtist, SongAlbum, SongGenre, SongLength, SongLocation)
VALUES
(var1, var2, var3, var4, var5, var6)
""")
有人可以帮我解决这里的语法吗?
答案 0 :(得分:227)
请注意对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语句中的参数的修饰符在不同的DB API实现之间有所不同,并且mysql客户端库使用printf
样式语法而不是更常被接受的'?'标记(由例如。python-sqlite
使用)。
答案 1 :(得分:38)
您有几个选择。你会想要熟悉python的字符串iterpolation。当你想知道这样的事情时,你可能会在将来寻找更多成功的术语。
更适合查询:
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”外观:)
答案 2 :(得分:14)
链接的文档提供以下示例:
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)。
答案 3 :(得分:5)
实际上,即使你的变量(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为什么在字符串中使用%s?因为MySQLdb会将其转换为SQL文字值,即字符串'5'。当它完成后,查询实际上会说“......价格<5”。
答案 4 :(得分:5)
作为所选答案的替代方案,并且使用与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()
答案 5 :(得分:0)
这是另一种方法。它在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)
答案 6 :(得分:0)
第一个解决方案效果很好。我想在这里添加一个小细节。确保您要替换/更新的变量必须为str类型。我的mysql类型是十进制,但是我必须将参数变量设置为str才能执行查询。
temp = "100"
myCursor.execute("UPDATE testDB.UPS SET netAmount = %s WHERE auditSysNum = '42452'",(temp,))
myCursor.execute(var)