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 循环都产生了相似的性能。