Python多进程 - 初始化/传递数据库连接的最佳方法以在进程间使用

5
我在使用Python的多进程包multiprocessing时,使用pool.map方法传递数据库连接对象或游标对象遇到了一些困难。基本上,我想创建一个拥有各自状态和数据库连接的工作线程池,以便他们可以并行执行查询。

我尝试过以下方法,但是在Python中使用它们时会出现pickling错误 -

Pool Map with 2 arugements

Use Initializer to set up multiprocess pool

第二个链接正是我需要做的事情,也就是说,每个进程在启动时都要打开一个数据库连接,然后使用该连接来处理传递的数据/参数。

以下是我的代码:

import multiprocessing as mp

def process_data((id,db)):
  print 'in processdata'
  cursor = db.cursor()
  query = ....
  #cursor.execute(query)
  #....
  .....
  .....
  return row

`if __name__ == '__main__':

  db = getConnection() 
  cursor = db.cursor() 
  print 'Initialised db connection and cursor'
  inputs = [1,2,3,4,5]
  pool = mp.Pool(processes=2)
  result_list = pool.map(process_data,zip(inputs,repeat(db)))
  #print result_list
  pool.close()
  pool.join() 

这会导致以下错误 -
`Exception in thread Thread-1:
  Traceback (most recent call last):
  File "/usr/lib/python2.6/threading.py", line 532, in __bootstrap_inner
    self.run()
  File "/usr/lib/python2.6/threading.py", line 484, in run
    self.__target(*self.__args, **self.__kwargs)
  File "/usr/lib/python2.6/multiprocessing/pool.py", line 225, in _handle_tasks
    put(task)
  PicklingError: Can't pickle <type 'module'>: attribute lookup __builtin__.module failed`

我猜db或游标对象根据Python的规定不可序列化,因为如果我将repeat(db)替换为repeat(x),其中x是int或string,它会起作用。 我尝试使用初始化函数,一开始似乎有效,但在执行查询时会发生奇怪的事情,许多查询返回id为空,而实际上存在数据。

如何最好地实现这个? 我正在使用Linux机器上的Python 2.6.6。


4
你可能不想传递数据库连接。它们无法序列化。如果你的子程序需要访问数据库,他们可能需要建立自己的连接。 - g.d.d.c
2个回答

10

我会将我的评论作为答案发布,因为我认为这是合适的。你不想尝试从父进程传递数据库连接到子进程。你应该将静态数据或其他可序列化的对象移动到子进程中。你可以传递数据行等等。或者让你的子进程在需要时建立自己的数据库连接。


-2

1
通常情况下,当传递一个数据库连接时,pickle会抛出异常(我已经遇到过很多次了,你需要将其从保存状态中移除),因此似乎不是一个明智的选择。 - JL Peyret

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接