简体   繁体   English

使用`executemany`更新现有SQLite3数据库中的条目(使用Python sqlite3)

[英]Using `executemany` to update entries in an existing SQLite3 database (using Python sqlite3)

I know that executemany can be used to conveniently add new entries to a database; 我知道executemany可以用来方便地将新条目添加到数据库中; useful to reduce the Python method-call overheads compared to single execute s in a for loop. 与for循环中的单个execute s相比,减少Python方法调用开销很有用。 However, I am wondering if this could work with SQLite's UPDATE . 但是,我想知道这是否适用于SQLite的UPDATE

More concretely, consider the following setup: 更具体地说,请考虑以下设置:

cnx = sqlite3.connect(DATABASE)
c = cnx.cursor()
for path in paths:
    for data in some_computation(path):
        c.execute("UPDATE TABLENAME SET cont=? WHERE id=?", (data[1], data[0]))
cnx.commit()
cnx.close()

I am not even sure if the approach below would be any faster (would have to benchmark it), but the problem is that it doesn't work, because I am doing it incorrectly I assume. 我甚至不确定下面的方法是否会更快(必须对它进行基准测试),但问题是它不起作用,因为我做错了我假设。 Any tips to use executemany in the code snippet below to accomplish the task that I posted above? executemany在下面的代码片段中使用executemany来完成我上面发布的任务的提示吗?

cnx = sqlite3.connect(DATABASE)
c = cnx.cursor()

for path in paths:
    data_ids, data_conts = [], []
    for data in some_computation(path):
        if len(data_ids) >= CHUNKSIZE:
            c.executemany("UPDATE TABLENAME SET cont=? WHERE id=?", (data_conts, data_ids))
            cnx.commit()
            data_ids, data_conts = [], []
        data_ids.append(data[0])
        data_conts.append(data[1])
    c.executemany("UPDATE TABLENAME SET cont=? WHERE id=?", (data_conts, data_ids))      
    cnx.commit()

cnx.commit()
cnx.close()

Many thanks for tips and insights! 非常感谢您的提示和见解!

EDIT 1: 编辑1:

The problem with the bottom example: 底部示例的问题:

ProgrammingError: Incorrect number of bindings supplied. The current statement uses 2, and there are 50000 supplied.

(where CHUNKSIZE=50000) (其中CHUNKSIZE = 50000)

EDIT 2: 编辑2:

The same error occurs 发生同样的错误

cnx = sqlite3.connect(DATABASE)
c = cnx.cursor()

for path in paths:
    data_conts = []
    for data in some_computation(path):
        if len(data_ids) >= CHUNKSIZE:
            c.executemany("UPDATE TABLENAME SET cont=? WHERE id=?", (data_conts,))
            cnx.commit()
            data_conts = []

        data_conts.append([data[1], data[0]])
    c.executemany("UPDATE TABLENAME SET cont=? WHERE id=?", (data_conts,))   
    cnx.commit()

cnx.commit()
cnx.close()

but thanks to @falsetru I then noticed my error, It should be 但感谢@falsetru我注意到我的错误,应该是

... WHERE id=?", data_conts)

and not 并不是

... WHERE id=?", (data_conts,))

You need to pass a sequence of sequences ( [[cont,id], [cont,id], [cont,id], ...] , not [cont, cont, cont, ...], [id, id, id, ..] ): 你需要传递一系列序列( [[cont,id], [cont,id], [cont,id], ...] ,而不是[cont, cont, cont, ...], [id, id, id, ..] ):

for path in paths:
    params = []
    for data in some_computation(path):
        if len(data_ids) >= CHUNKSIZE:
            c.executemany("UPDATE TABLENAME SET cont=? WHERE id=?", params)
            cnx.commit()
            params = []
        params.append([data[1], data[0]])
    if params:
        c.executemany("UPDATE TABLENAME SET cont=? WHERE id=?", params)
    cnx.commit()

what you have is perfect except that you should use zip(conts,ids) where conts and ids are lists. 你所拥有的是完美的,除了你应该使用zip(conts,id),其中conts和id是列表。 This does the rearrangement automatically for you. 这会自动为您重新排列。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM