Python MySQLdb 将列表传递到插入语句中

Python MySQLdb passing a list into an insert statement

我正在尝试将列表中的一些值传递到插入语句中,我认为这很简单,但我发现自己在这上面浪费了太多时间:

有人能解释一下这里出了什么问题吗?

使用硬编码值列表工作

cursor=db.cursor()
cursor.execute(" INSERT INTO a (a,b) VALUES (%s,%s)", ('abc', 'abc'))
db.commit()
cursor.close()

不能将值列表用作变量 (output_insert)

output = ('abc','abc')
output_insert = str(output)
cursor=db.cursor()
sql = '" INSERT INTO a (a,b) VALUES (%s,%s)",' +  output_insert
cursor.execute(sql)
db.commit()
cursor.close()

如果我打印第二个语句,我可以看到它与第一个失败的语句相同:

打印sql

" 插入 (a,b) 值 (%s,%s)",('abc', 'abc')

同于:

" 插入 (a,b) 值 (%s,%s)", ('abc', 'abc')

返回的错误是:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/dist-packages/MySQLdb/cursors.py", line 174, in execute
    self.errorhandler(self, exc, value)
  File "/usr/lib/python2.7/dist-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
    raise errorclass, errorvalue
_mysql_exceptions.ProgrammingError: (1064, 'You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near \'" INSERT INTO a (a,b) VALUES (%s,%s)",(\'abc\', \'abc\')\' at line 1')

谢谢!

不要使用字符串插值或字符串格式化来创建 SQL 查询。 您会使代码容易受到 SQL injection 攻击并进行类型转换和报价处理问题(正如您已经看到的那样)。

相反,参数化您的查询。查询参数应作为单独的参数传递给 execute():

output = ('abc','abc')
sql = """
    INSERT INTO 
        a 
        (a, b) 
    VALUES 
        (%s, %s)"""
cursor.execute(sql, output)

如果打印 sql 你给 mysql:

" INSERT INTO a (a,b) VALUES (%s,%s)",('abc', 'abc')

MySQL 不是正确的 sql,所以你出错了。

或者您可以使用字符串格式化方法来格式化sql,例如:

cursor=db.cursor()
vars_sql = ('abc', 'abc')
sql_format = "INSERT INTO a (a,b) VALUES ('{0}','{1}')"
real_sql = sql_format.format(*vars_sql)
# print out see if sql is correct
print real_sql
# not use format string avoid dangerous
cursor.execute("INSERT INTO a (a,b) VALUES ('%s','%s')", ('abc', 'abc'))
db.commit()
cursor.close()

这样就可以打印出真正的sql,在MySQL中执行,看看sql有没有问题。