在后台调度程序函数回调中执行数据库查询和更新

时间:2018-07-13 19:18:09

标签: python multithreading sqlalchemy flask-sqlalchemy apscheduler

我有一个flask应用程序,它使用BackgroundScheduler(APScheduler)执行一个函数,该函数包括查询和更新数据库(flask-sqlalchemy) 由于后台调度,功能是从单独的线程调用的

Traceback (most recent call last):
  File "D:\xx\venv\lib\site-packages\sqlalchemy\util\_collections.py", line 999, in __call__
    return self.registry[key]

经过一些研究,我猜想是因为会话是线程本地的。我还尝试生成新的观点: Multi-threaded use of SQLAlchemy 但是没有用

我还考虑过将工作推迟到主线程,但是我不知道在我的情况下如何工作

有没有办法在单独的线程中执行数据库操作,还是有办法将工作推回主线程?

我使用BackgroundScheduler,执行的功能如下:

foo(..):
u = User.query.filter_by(..).first()
...

我也尝试过

foo(..):
db.session.query.filter_by(..).first()
...

其中db是SQLAlchemy()的实例(来自flask_sqlalchemy)

无法使用BlockScheduler,因为它会阻塞我的整个烧瓶应用程序

编辑(由于请求):

此刻我使用SQLight

_execute_construction 是执行的功能

127.0.0.1 - - [13/Jul/2018 21:36:00] "POST /construct/structures HTTP/1.1" 302 -
Job "_execute_construction (trigger: date[2018-07-13 19:40:00 CEST], next run at: 2018-07-13 19:40:00 CEST)" raised an exception
Traceback (most recent call last):
  File "D:\..\venv\lib\site-packages\sqlalchemy\util\_collections.py", line 999, in __call__
    return self.registry[key]
KeyError: 2384

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "D:\..\venv\lib\site-packages\apscheduler\executors\base.py", line 125, in run_job
    retval = job.func(*job.args, **job.kwargs)
  File "D:\..\app\construct\handlers.py", line 59, in _execute_construction
    construction = db.session.query(User).filter_by(id=1).first()
  File "D:\..\venv\lib\site-packages\sqlalchemy\orm\scoping.py", line 153, in do
    return getattr(self.registry(), name)(*args, **kwargs)
  File "D:\..\venv\lib\site-packages\sqlalchemy\util\_collections.py", line 1001, in __call__
    return self.registry.setdefault(key, self.createfunc())
  File "D:\..\venv\lib\site-packages\sqlalchemy\orm\session.py", line 2950, in __call__
    return self.class_(**local_kw)
  File "D:\..\venv\lib\site-packages\flask_sqlalchemy\__init__.py", line 141, in __init__
    self.app = app = db.get_app()
  File "D:..\venv\lib\site-packages\flask_sqlalchemy\__init__.py", line 912, in get_app
    'No application found. Either work inside a view function or push'
RuntimeError: No application found. Either work inside a view function or push an application context. See http://flask-sqlalchemy.pocoo.org/contexts/.
127.0.0.1 - - [13/Jul/2018 21:36:00] "GET /construct/structures HTTP/1.1" 200 -

0 个答案:

没有答案