Jeg tror på TypeError kommer fra multiprocessing 's get .
Jeg har fjernet al DB-koden fra dit script. Tag et kig på dette:
import multiprocessing
import sqlalchemy.exc
def do(kwargs):
i = kwargs['i']
print i
raise sqlalchemy.exc.ProgrammingError("", {}, None)
return i
pool = multiprocessing.Pool(processes=5) # start 4 worker processes
results = []
arglist = []
for i in range(10):
arglist.append({'i':i})
r = pool.map_async(do, arglist, callback=results.append) # evaluate "f(10)" asynchronously
# Use get or wait?
# r.get()
r.wait()
pool.close()
pool.join()
print results
Bruger r.wait returnerer det forventede resultat, men ved hjælp af r.get rejser TypeError . Som beskrevet i pythons dokumenter
, brug r.wait efter en map_async .
Rediger :Jeg er nødt til at ændre mit tidligere svar. Jeg tror nu på TypeError kommer fra SQLAlchemy. Jeg har ændret mit script for at genskabe fejlen.
Rediger 2 :Det ser ud til, at problemet er, at multiprocessing.pool spiller ikke godt, hvis en arbejder rejser en undtagelse, hvis konstruktør kræver en parameter (se også her
).
Jeg har ændret mit manuskript for at fremhæve dette.
import multiprocessing
class BadExc(Exception):
def __init__(self, a):
'''Non-optional param in the constructor.'''
self.a = a
class GoodExc(Exception):
def __init__(self, a=None):
'''Optional param in the constructor.'''
self.a = a
def do(kwargs):
i = kwargs['i']
print i
raise BadExc('a')
# raise GoodExc('a')
return i
pool = multiprocessing.Pool(processes=5)
results = []
arglist = []
for i in range(10):
arglist.append({'i':i})
r = pool.map_async(do, arglist, callback=results.append)
try:
# set a timeout in order to be able to catch C-c
r.get(1e100)
except KeyboardInterrupt:
pass
print results
I dit tilfælde, da din kode rejser en SQLAlchemy-undtagelse, er den eneste løsning, jeg kan komme i tanke om, at fange alle undtagelserne i do funktion og re-hæve en normal Exception i stedet. Noget som dette:
import multiprocessing
class BadExc(Exception):
def __init__(self, a):
'''Non-optional param in the constructor.'''
self.a = a
def do(kwargs):
try:
i = kwargs['i']
print i
raise BadExc('a')
return i
except Exception as e:
raise Exception(repr(e))
pool = multiprocessing.Pool(processes=5)
results = []
arglist = []
for i in range(10):
arglist.append({'i':i})
r = pool.map_async(do, arglist, callback=results.append)
try:
# set a timeout in order to be able to catch C-c
r.get(1e100)
except KeyboardInterrupt:
pass
print results
Rediger 3 :så det ser ud til at være en fejl med Python , men korrekte undtagelser i SQLAlchemy ville løse det:derfor har jeg rejst problemet med SQLAlchemy også.
Som en løsning på problemet tror jeg, at løsningen er i slutningen af Rediger 2 ville gøre (indpakning af tilbagekald i try-except og re-raise).