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有没有问题。
我正在尝试将列表中的一些值传递到插入语句中,我认为这很简单,但我发现自己在这上面浪费了太多时间:
有人能解释一下这里出了什么问题吗?
使用硬编码值列表工作
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有没有问题。