【问题标题】:sqlite3.InterfaceError: Error binding parameter 0 - probably unsupported type?sqlite3.InterfaceError:错误绑定参数 0 - 可能是不支持的类型?
【发布时间】:2021-02-19 23:09:43
【问题描述】:

尝试将数据从 Python(3.9.1) 编译到 SQLite3 时出现错误。

import sqlite3

conn = sqlite3.connect('newdB.db')

#Creates the table 'tbl_newdb' with an incrementing ID, and 'db_type' columns.
with conn:
    cur = conn.cursor()
    cur.execute("CREATE TABLE IF NOT EXISTS tbl_newdb( \
        ID INTEGER PRIMARY KEY AUTOINCREMENT, \
        db_type TEXT)")
    conn.commit()
conn.close()

conn = sqlite3.connect('newdB.db')

#Our list of data we will be grabbing from to fill the tables.
with conn:
    cur = conn.cursor()
    fileList = "information.docx","Hello.txt","myImage.png","myMovie.mpg","World.txt","data.pdf","myPhoto.jpg"
    cur.execute("INSERT INTO tbl_newdb (db_type) VALUES (?)",(fileList,))
    conn.commit()
conn.close()

这是我从 IDLE shell 收到的错误消息:

 line 22, in <module>
    cur.execute("INSERT INTO tbl_newdb (db_type) VALUES (?)",(str(fileList,)))
sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 1, and there are 103 supplied.

【问题讨论】:

  • 错误信息与您的代码不匹配。在错误消息中,fileList 元组正在转换为字符串,但发布的代码并没有这样做。问题标题也不同。您已经从 @pop 获得了答案,但在以后的问题中发布输入、输出和代码时,请尽量保持同步。

标签: python sql database sqlite


【解决方案1】:

TLDR:execute 接受两个参数,一个 SQL 查询和一个输入列表,SQL 中的每个 (?) 参数都有一个元素。

您想要的是executemany,它接受输入列表的列表。解决方案如下所示:

import sqlite3

# Create a database in memory for testing
conn = sqlite3.connect('newdB.db')

# Execute with the databse connection
with conn:
    cur = conn.cursor()

    # Create your table in the in-memory database
    cur.execute("""
    CREATE TABLE IF NOT EXISTS tbl_newdb(
        ID INTEGER PRIMARY KEY AUTOINCREMENT,
        db_type TEXT
    )
    """)
    conn.commit()

# A list of parameters to pass to queries
# Notice we are making a list of lists
# `execute` takes a list of inputs for a single execution
parameterList = [
    ["information.docx"],
    ["Hello.txt"],
    ["myImage.png"],
    ["myMovie.mpg"],
    ["World.txt"],
    ["data.pdf"],
    ["myPhoto.jpg"],
]

with conn:
    # Execute the same query multiple times
    # Because we are passing one value to our sql, each list in parameterList
    # only has one element.
    cur.executemany(
        "INSERT INTO tbl_newdb(db_type) VALUES(?)",
        parameterList
    )
    conn.commit()

    # Print debugging information to prove we inserted things correctly
    cur.execute("SELECT db_type FROM tbl_newdb")
    print(cur.fetchall())

# Close the connection after creating the table
conn.close()

注意我使用 [...] 语法而不是元组 (...,) 语法。两者都可以,为了清楚起见,我更喜欢方括号,因为我们有很多单元素列表。

您也可以用这样的 for 循环替换 cur.exeutemany(...)

一点解释:execute 接受两个参数,一个 SQL 查询和一个参数列表。您可以将参数列表视为 SQL 查询中每个 (?) 的替换。第一个 (?) 被替换为参数列表中的第一个元素,第二个 (?) 被替换为列表中的第二个元素,依此类推。

让我们弄清楚我们是如何到达这里的。当我第一次运行你的代码时,我得到了这个输出:

Traceback (most recent call last):
  File "alt.py", line 20, in <module>
    cur.execute("INSERT INTO tbl_newdb (db_type) VALUES (?)",(fileList,))
sqlite3.InterfaceError: Error binding parameter 0 - probably unsupported type.

unsupported type 是对我的暗示,您将fileList 放入已经是一个元组的fileList,并将其包装在另一个元组中。所以我将execute 行更改为:

cur.execute("INSERT INTO tbl_newdb (db_type) VALUES (?)", fileList)

接下来我们得到这个错误:

Traceback (most recent call last):
  File "alt.py", line 20, in <module>
    cur.execute("INSERT INTO tbl_newdb (db_type) VALUES (?)", fileList)
sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 1, and there are 7 supplied.

这很奇怪。它把我列出的 7 样东西都列在一个装订里了?有趣的。如果我们将fileList 缩短为一个元素会怎样?从小处着手,看看我们能得到什么。我将execute 上方的行更改为

fileList = "information.docx"

我们得到一个类似但不同的错误:

Traceback (most recent call last):
  File "alt.py", line 20, in <module>
    cur.execute("INSERT INTO tbl_newdb (db_type) VALUES (?)", fileList)
sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 1, and there are 16 supplied.

嗯。 16 是 "information.docx" 中的字符数,因此 Python 必须将该字符串视为参数列表。让我们把它包装在一个列表中,看看会发生什么:

fileList = ["information.docx"]

由此我们获得了第一个成功!

如果我们向列表中添加另一个元素会发生什么?

fileList = ["information.docx", "other_file.txt"]
Traceback (most recent call last):
  File "alt.py", line 20, in <module>
    cur.execute("INSERT INTO tbl_newdb (db_type) VALUES (?)", fileList)
sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 1, and there are 2 supplied.

科学!它成功了一个元素,但失败了两个。这意味着execute 的第二个参数需要是一个列表,其元素与我们的 SQL 查询中的(?) 参数一样多。

现在我们有几个选择。我们可以read the SQLite Python docs and discoverexecutemany,也可以做一个for循环:

for f in fileList:
    parameters = [f]
    cur.execute("INSERT INTO tbl_newdb (db_type) VALUES (?)", parameters)
conn.commit()

SQLite 非常快,所以executemany 和 for 循环都产生了相似的性能。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-24
    相关资源
    最近更新 更多