apscheduler: Using sqlalchemy datastore with another sqalchem instance "TypeError: can't pickle _thread._local objects"
Application is throwing TypeError: can't pickle _thread._local objects
when I am using another sqlalchemy instance
Expected Behavior
apscheduler should work.
Current Behavior
I have application that instantiates a class that has methods that use sqlalchemy
Steps to Reproduce
- Use whatever scheduler with sqlalchemy backed
- Create another modules with a class that has method that uses sqlalchemy
- Start scheduler and call a method that uses sqlalchemy
Dump
TypeError: can't pickle _thread._local objects
apscheduler.scheduler - INFO - Adding job tentatively -- it will be properly scheduled when the scheduler starts
Traceback (most recent call last):
File "scheduler.py", line 65, in <module>
sched.start()
File "C:\Users\admin\AppData\Local\Programs\Python\Python37\lib\site-packages\apscheduler\schedulers\background.py", line 33, in start
BaseScheduler.start(self, *args, **kwargs)
File "C:\Users\admin\AppData\Local\Programs\Python\Python37\lib\site-packages\apscheduler\schedulers\base.py", line 162, in start
self._real_add_job(job, jobstore_alias, replace_existing)
File "C:\Users\admin\AppData\Local\Programs\Python\Python37\lib\site-packages\apscheduler\schedulers\base.py", line 867, in _real_add_job
store.add_job(job)
File "C:\Users\admin\AppData\Local\Programs\Python\Python37\lib\site-packages\apscheduler\jobstores\sqlalchemy.py", line 95, in add_job
'job_state': pickle.dumps(job.__getstate__(), self.pickle_protocol)
TypeError: can't pickle _thread._local objects
If you need more info just let me know
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 19 (10 by maintainers)
@skjoher @ersaijun @ziyueWu @aidiss
If you run into this issue and don’t know how to
change your architecture.
then read the following:We create an instance of
MyClass
that contains a field that cannot be pickled -self.ssl_context
. We then attempt to schedule a therun_task
method using APS, which like Alex outlined above will attempt to pickle all fields of themy_class
instance.To solve this, let’s avoid pickling
ssl_context
and recreate it manually upon unpickling instead:This method then applies to whatever is causing your pickling issues. Look around your code, find out what can’t be pickled and use this destroy-and-rebuild method. Bear in mind that this may not work for every case (as some objects cannot be rebuilt like this correctly), but chances are your class can indeed be rewritten. Remember that this rebuilding can use objects that were successfully pickled by accessing the
state
!Funny enough, the APS schedulers themselves cannot be pickled either. Make sure that none of your pickled classes store any APS schedulers, ie. don’t do this:
Or if you do, make sure to delete the scheduler on pickling, and recreate it (including its jobs!) on unpickling.
You can read more in this article on Medium.
Good luck! 👋
Thanks. I understand now.
so,I canot use jobstores when I add a job of an instance. The code like this:
it will cause error : TypeError: can’t pickle _thread.lock objects
Is there any method to solve the problem?
Serializing means converting an in-memory object to a bytestream that can be saved to persistent storage and later restored from there. An instance method is a function bound to an instance of a class. When you schedule a job that targets an instance method, that instance must be serialized along with the reference to the method definition in order for the restoration to be possible.