Python的多与pyodbc数据库访问“不安全”?(Python multiprocessing

2019-07-21 11:38发布

问题:

我正在以下回溯,不明白这意味着什么或如何解决它:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "C:\Python26\lib\multiprocessing\forking.py", line 342, in main
    self = load(from_parent)
  File "C:\Python26\lib\pickle.py", line 1370, in load
    return Unpickler(file).load()
  File "C:\Python26\lib\pickle.py", line 858, in load
    dispatch[key](self)
  File "C:\Python26\lib\pickle.py", line 1083, in load_newobj
    obj = cls.__new__(cls, *args)
TypeError: object.__new__(pyodbc.Cursor) is not safe, use pyodbc.Cursor.__new__()

这种情况:

我有要处理的SQL Server数据库的完整数据的。 我试图用多模块并行工作,并把我的电脑上的多核的优势。 我一般的类结构如下:

  • MyManagerClass
    • 这是主类,其中程序将启动。
    • 它创建两个multiprocessing.Queue对象,一个work_queue和一个write_queue
    • 它还创建并启动其他进程,然后等待他们完成。
    • 注:这是不是 multiprocessing.managers.BaseManager的扩展()
  • MyReaderClass
    • 这个类读取从SQL Server数据库中的数据。
    • 它把项目的work_queue
  • MyWorkerClass
    • 这是工作的处理情况。
    • 它从项目work_queue并把完成的项目write_queue
  • MyWriterClass
    • 这个类是负责写处理的数据返回给SQL Server数据库。
    • 它从项目write_queue

我们的想法是,将有一个经理,一个读卡器,一个作家,和许多工人。

其他详情:

我得到的回溯两次在标准错误,所以我想,这对作家来说,发生一次为读者和一次。 我的工作进程获得创建罚款,但只是坐在那里,直到我发一个KeyboardInterrupt因为他们没有在work_queue

无论是读者与作者有自己的数据库连接,在初始化时创建的。

解:

由于马克和费迪南德·拜尔对他们的答案和问题,导致这一解决方案。 他们理所当然地指出,Cursor对象不是“泡菜-能”,这是多使用在进程间传递信息的方法。

我的代码的问题是, MyReaderClass(multiprocessing.Process)MyWriterClass(multiprocessing.Process)都连接到数据库中的__init__()方法。 我创建了两个对象(即所谓的init()方法)在MyManagerClass ,然后叫start()

因此,这将创建连接和游标对象,然后尝试通过咸菜把它们发送到子进程。 我的解决办法是把连接和光标对象的实例移到run()方法,它不叫,直到子进程是完全建立。

Answer 1:

多处理依赖于酸洗过程之间进行通信的对象。 的pyodbc连接和光标对象不能被酸洗。

>>> cPickle.dumps(aCursor)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python2.5/copy_reg.py", line 69, in _reduce_ex
    raise TypeError, "can't pickle %s objects" % base.__name__
TypeError: can't pickle Cursor objects
>>> cPickle.dumps(dbHandle)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python2.5/copy_reg.py", line 69, in _reduce_ex
    raise TypeError, "can't pickle %s objects" % base.__name__
TypeError: can't pickle Connection objects

“这使在work_queue项目”,哪些项目? 是否有可能光标对象获得通过呢?



Answer 2:

该错误是在中引发了pickle模块,让您的某处DB-Cursor对象被封装和拆封(再次序列化到存储和反序列化的Python对象)。

我想这pyodbc.Cursor不支持酸洗。 为什么你应该尝试无论如何坚持光标对象?

检查你使用pickle在你的工作链或如果使用隐含的地方。



Answer 3:

pyodbc有Python的DB-API threadsafety 1级 。 这意味着线程不能共享连接,并且它不是线程安全的。

我不认为底层线程安全的ODBC驱动程序有所作为。 它在Python代码由酸洗错误指出。



文章来源: Python multiprocessing and database access with pyodbc “is not safe”?