Vex*_*ior 2 python sql database sqlite
尝试将数据从 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()
Run Code Online (Sandbox Code Playgroud)
这是我从 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.
Run Code Online (Sandbox Code Playgroud)
小智 5
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()
Run Code Online (Sandbox Code Playgroud)
注意我使用了 use[...]语法而不是元组(...,)语法。两者都可以,为了清晰起见,我只是更喜欢方括号,因为我们有很多单元素列表。
您还可以cur.exeutemany(...)用 for 循环替换,如下所示:
一些解释: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.
Run Code Online (Sandbox Code Playgroud)
unsupported type向我暗示,您正在将fileList它已经是一个元组,并将其包装在另一个元组中。所以我将该execute行更改为:
cur.execute("INSERT INTO tbl_newdb (db_type) VALUES (?)", fileList)
Run Code Online (Sandbox Code Playgroud)
接下来我们得到这个错误:
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.
Run Code Online (Sandbox Code Playgroud)
这很奇怪。它正在获取我列出的 7 件事并试图将它们塞进一个绑定中?有趣的。如果我们缩短fileList为只有一个元素怎么办?从小事做起,看看我们能取得什么成果。我将上面的行更改execute为
fileList = "information.docx"
Run Code Online (Sandbox Code Playgroud)
我们得到一个类似但不同的错误:
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.
Run Code Online (Sandbox Code Playgroud)
唔。16 是其中的字符数"information.docx",因此 Python 必须将该字符串视为参数列表。让我们将其包装在一个列表中,看看会发生什么:
fileList = ["information.docx"]
Run Code Online (Sandbox Code Playgroud)
这样我们就取得了第一次成功!
如果我们向列表中添加另一个元素会发生什么?
fileList = ["information.docx", "other_file.txt"]
Run Code Online (Sandbox Code Playgroud)
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.
Run Code Online (Sandbox Code Playgroud)
科学!它在一个元素上成功,但在两个元素上失败。这意味着第二个参数execute需要是一个列表,其中的元素数量与(?)SQL 查询中的参数数量相同。
现在我们有几个选择。我们可以阅读 SQLite Python 文档并发现 executemany,或者我们可以执行 for 循环:
for f in fileList:
parameters = [f]
cur.execute("INSERT INTO tbl_newdb (db_type) VALUES (?)", parameters)
conn.commit()
Run Code Online (Sandbox Code Playgroud)
SQLite 非常快,因此executemany和 for 循环都产生相似的性能。