Beh*_*ali 2 python sqlite multiprocessing
我有一个简单的函数,将一些计算的输出写入sqlite表中。我想在Python中通过多处理并行使用此函数。我的具体问题是,当每个进程尝试将其结果写入同一张表时,如何避免冲突?运行代码给我这个错误:sqlite3.OperationalError:数据库被锁定。
import sqlite3
from multiprocessing import Pool
conn = sqlite3.connect('test.db')
c = conn.cursor()
c.execute("CREATE TABLE table_1 (id int,output int)")
def write_to_file(a_tuple):
index = a_tuple[0]
input = a_tuple[1]
output = input + 1
c.execute('INSERT INTO table_1 (id, output)' 'VALUES (?,?)', (index,output))
if __name__ == "__main__":
p = Pool()
results = p.map(write_to_file, [(1,10),(2,11),(3,13),(4,14)])
p.close()
p.join()
Traceback (most recent call last):
sqlite3.OperationalError: database is locked
Run Code Online (Sandbox Code Playgroud)
用一个 Pool是个好主意。
我看到了三种可能的解决方案。
首先,不要让池工作程序尝试将数据插入数据库,而是让工作程序将数据返回给父进程。
在父进程中,使用imap_unordered代替map。这是一个迭代过程,一旦可用就开始提供值。然后,父级可以将数据插入数据库。
这将序列化对数据库的访问,从而避免了该问题。
如果要插入到数据库中的数据相对较小,但是更新经常发生,则首选此解决方案。因此,与计算数据相比,更新数据库需要花费相同或更多的时间。
其次,您可以使用Lock。然后,工人应该
这将避免将数据发送到父进程的开销。但是,相反,您可能会让工作人员停滞不前,等待将其数据写入数据库。
如果要插入的数据量很大,但是计算数据比将数据插入数据库要花费更长的时间,则这将是首选解决方案。
第三,您可以让每个工作人员写入其自己的数据库,然后将它们合并。您可以直接在sqlite甚至Python中执行此操作。尽管有大量数据,但我不确定后者是否有优势。