gpt4 book ai didi

使用 pyodbc "is not safe"进行 Python 多处理和数据库访问?

转载 作者:太空狗 更新时间:2023-10-29 18:26:04 27 4
gpt4 key购买 nike

问题:

我收到以下回溯,但不明白它的含义或如何修复它:

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 数据库。我正在尝试使用多处理模块来并行化工作并利用我计算机上的多个内核。我的一般类结构如下:

  • 我的经理类
    • 这是主类,程序从这里开始。
    • 它创建两个 multiprocessing.Queue 对象,一个 work_queue 和一个 write_queue
    • 它还会创建并启动其他进程,然后等待它们完成。
    • 注意:这不是 multiprocessing.managers.BaseManager() 的扩展
  • MyReaderClass
    • 此类从 SQL Server 数据库中读取数据。
    • 它将项目放入 work_queue
  • 我的 worker 类(Class)
    • 这是工作处理发生的地方。
    • 它从 work_queue 中获取项目并将完成的项目放入 write_queue
  • 我的作家类
    • 该类负责将处理后的数据写回SQL Server数据库。
    • 它从 write_queue 中获取项目。

想法是,将有一位经理、一位读者、一位作家和许多 worker 。

其他细节:

我在 stderr 中得到了两次回溯,所以我认为它对读者发生一次,对作者发生一次。我的工作进程创建得很好,但只是坐在那里直到我发送 KeyboardInterrupt,因为它们在 work_queue 中没有任何内容。

读取器和写入器都有自己的数据库连接,在初始化时创建。

解决方案:

感谢 Mark 和 Ferdinand Beyer 的回答和提出的问题,促成了这个解决方案。他们正确地指出 Cursor 对象不是“pickle-able”的,这是 multiprocessing 用来在进程之间传递信息的方法。

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

因此它会创建连接和游标对象,然后尝试通过 pickle 将它们发送到子进程。我的解决方案是将连接和游标对象的实例化移动到 run() 方法,该方法在子进程完全创建之前不会被调用。

最佳答案

多处理依赖于 pickle 来在进程之间传递对象。 pyodbc 连接和游标对象不能被 pickle。

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

“它将项目放入工作队列”,什么项目?游标对象是否也可以通过?

关于使用 pyodbc "is not safe"进行 Python 多处理和数据库访问?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1537809/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com