2015-11-19 63 views
4

我知道executemany可以方便地将新条目添加到数据库;与for循环中的单个execute相比,可用于减少Python方法调用开销。但是,我想知道这是否可以与SQLite的UPDATE一起使用。使用`executemany`来更新现有SQLite3数据库中的条目(使用Python sqlite3)

更具体地,请考虑以下设置:

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

我甚至不知道下面的方法将是任何更快(将不得不基准),但问题是,这是行不通的,因为我假设我做错了。在下面的代码片段中使用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() 

非常感谢您的提示和见解!

EDIT 1:

与底部例子的问题:

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

(其中CHUNKSIZE = 50000)

编辑2:

发生同样的错误

​​

但由于@falsetru然后我发现我的错误,它应该是

... WHERE id=?", data_conts) 

,而不是

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

回答

8

您需要通过序列的序列([[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() 
+0

谢谢,我之前尝试过类似的东西,但是我不小心传递了'[[cont,id],[cont,id],[cont,id],...]]'这就是为什么它没有工作 – Sebastian

0

你有什么是完美的除了你应该我们e zip(conts,ids)conts和id是列表。这会自动为您重新排列。