【问题标题】:Python 3 SQLite3 - Incorrect number of bindingsPython 3 SQLite3 - 绑定数量不正确
【发布时间】:2016-01-01 22:49:09
【问题描述】:

我知道 Stack Overflow 上有很多关于这个错误的问题,但我尝试了很多解决方案,显然它们都失败了。

这是一个列表:

sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 1, and there are 74 supplied

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

我正在尝试将用户名和散列密码(由 PassLib - https://pythonhosted.org/passlib/ 创建)存储在 SQLite3 数据库中。这些分别存储在变量“targetusername”和“password”中。我的问题是,当我实际尝试将这两个变量插入到名为“Passwords”的数据库表中时,会出现以下错误:

Incorrect number of bindings supplied. The current statement uses 1, and there are 11 supplied.

以下是目标用户名和密码将存储的示例:

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"))

【问题讨论】:

    标签: python database python-3.x sqlite


    【解决方案1】:

    使用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(),因为只有一行数据被插入。

    【讨论】:

    • @user4884072:真的吗?我已经用一个完整的工作示例更新了我的答案。尝试运行它。我还建议您使用有效的代码更新您的问题(您的第一个示例结果为TypeError)并演示了问题。
    猜你喜欢
    • 2020-06-20
    • 1970-01-01
    • 2015-12-06
    • 2013-10-28
    • 2021-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-19
    相关资源
    最近更新 更多