문제점 :pyodbc로 파이썬 다중 처리 및 데이터베이스 액세스가 "안전하지 않습니다"?
나는 다음 역 추적을 얻고 그것이 무엇을 의미하는지 이해하지 못하거나 그것을 해결하는 방법 :
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
- 이 메인 클래스, 프로그램이 시작됩니다.
- 그것은 그들이 종료 될 때까지 하나
work_queue
하나 또한 생성하고 다른 프로세스를 시작write_queue
- 은 다음 대기이 multiprocessing.Queue 개체를 만듭니다.
- 참고 :이 하지 multiprocessing.managers.BaseManager의 확장()
- MyReaderClass
- 이 클래스는 SQL Server 데이터베이스에서 데이터를 읽고 있습니다.
work_queue
에 항목을 넣습니다.
- MyWorkerClass
- 작업 처리가 일어나는 곳이다.
work_queue
에서 항목을 가져오고 완료된 항목을write_queue
에 넣습니다.
- MyWriterClass
- 이 클래스는 다시 SQL Server 데이터베이스에 처리 된 데이터를 쓰는 담당하고있다.
write_queue
에서 항목을 가져옵니다.
아이디어는 하나의 관리자, 하나의 리더, 한 작가, 많은 노동자가있을 것입니다.
기타 사항 :
나는 열려진 두 번 역 추적을 얻을, 그래서 나는이 작가에 대해 한 번 독자에 대해 한 번 발생하는 것을 생각하고있다. 내 작업자 프로세스는 잘 작성되었지만 work_queue
에 아무 것도 없으므로 KeyboardInterrupt를 보낼 때까지 거기 앉아 있어야합니다.
리더와 작성자 모두 데이터베이스에 대한 자체 연결이 있으며 초기화시 작성됩니다.
솔루션 :이 솔루션을 주도 대답과 질문 마크와 페르디난트 바이어에
감사합니다. 그들은 Cursor 객체가 "pickle-able"이 아니라는 것을 정당하게 지적했다. 이것은 멀티 프로세싱이 프로세스간에 정보를 전달하는 방법이다.
내 코드의 문제점은 해당 __init__()
방법으로 데이터베이스에 연결된 MyReaderClass(multiprocessing.Process)
및 MyWriterClass(multiprocessing.Process)
입니다. MyManagerClass
에 두 개체 (예 : init 메서드라고 함)를 만든 다음 start()
이라고합니다.
그래서 연결 및 커서 객체를 만든 다음 피클을 통해 자식 프로세스로 전송하려고합니다. 내 솔루션은 연결 및 커서 개체의 인스턴스를 자식 프로세스가 완전히 생성 될 때까지 호출되지 않는 run() 메서드로 이동하는 것이 었습니다.
그냥 말하지만 : 훌륭한 질문입니다. – mavnn