我理解Stack Overflow上有很多关于此错误的问题,但我尝试了很多解决方案,显然它们都失败了。
这是一个清单:
SQLite parameter substitution problem
sqlite3.ProgrammingError: Incorrect number of bindings supplied
Reading from database with SQLite and Python: Incorrect number of binding supplied
SQLite Python Insert - Incorrect Number of Bindings Supplied
我正在尝试在SQLite3数据库中存储用户名和哈希密码(由PassLib创建 - https://pythonhosted.org/passlib/)。它们分别存储在变量“targetusername”和“password”中。我的问题是,当我实际尝试将这两个变量插入到名为“Passwords”的数据库表中时,它会出现此错误:
Incorrect number of bindings supplied. The current statement uses 1, and there are 11 supplied.
以下是targetusername和密码将存储的示例:
targetusername = "user4884072"
password = "$5$rounds=535000$ySH31paWMjEDCUUY$jdrBVGsoYnSMkdVBtjCaxQy2f0g3MX1Wts4vSYz7m.4"
此行显示错误:
c.executemany("INSERT INTO {tn} ({idf}, {cn}) VALUES(targetusername, %s" % str(password).\
format(tn="Passwords"))
它已被多次更改以尝试解决问题(这显然是由Python存储变量的方式引起的),但这是最初的原因:
c.execute("INSERT OR IGNORE INTO {tn} ({idf}, {cn}) VALUES (targetusername, password)".\
format(tn="Passwords", idf="Username", cn="Password"))
答案 0 :(得分:2)
使用c.execute()
而不是c.executemany()
来插入单行数据。这是您遇到错误的直接原因。
除此之外,不要使用字符串替换,使用参数化查询。这是一个完整的工作示例:
import sqlite3
connection = sqlite3.connect(':memory:') # in memory database
c = connection.cursor()
c.execute('create table Passwords (Username text, Password text)')
targetusername = "user4884072"
password = "$5$rounds=535000$ySH31paWMjEDCUUY$jdrBVGsoYnSMkdVBtjCaxQy2f0g3MX1Wts4vSYz7m.4"
c.execute('insert into Passwords (Username, Password) values (?, ?)', (targetusername, password))
print c.execute('select * from Passwords').fetchall()
输出:
[(u'user4884072', u'$5$rounds=535000$ySH31paWMjEDCUUY$jdrBVGsoYnSMkdVBtjCaxQy2f0g3MX1Wts4vSYz7m.4')]
在你发布的代码中,没有必要用值替换表名或列名,所以只需将它们放在查询字符串中,如图所示。
这使用参数化查询,其中API将用户名和密码的值插入到?
表示的位置的查询中。这比使用字符串替换更安全,因为DB API知道如何正确安全地转义传递给它的值,这可以避免对代码的SQL注入攻击。
它使用execute()
而不是executemany()
,因为只插入了一行数据。