Rad*_*odó 2 python multithreading flask
有点神秘的问题。
当所有代码都放在单个文件中时,从 Flask 应用程序生成线程效果很好app.py,但是当使用工厂模式时,应用程序上下文会丢失。
Exception in thread Thread-2:
Traceback (most recent call last):
File "/XXX/flaskthreading/venv/lib/python3.9/site-packages/sqlalchemy/util/_collections.py", line 1008, in __call__
127.0.0.1 - - [07/Jun/2022 14:06:53] "GET / HTTP/1.1" 200 -
return self.registry[key]
KeyError: <greenlet.greenlet object at 0x7f4f541ad040 (otid=0x7f4f54199d00) current active started main>
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/lib/python3.9/threading.py", line 954, in _bootstrap_inner
self.run()
File "/usr/lib/python3.9/threading.py", line 892, in run
self._target(*self._args, **self._kwargs)
File "/XXX/flaskthreading/app2/views.py", line 12, in printer
print(User.query.all())
File "/XXX/flaskthreading/venv/lib/python3.9/site-packages/flask_sqlalchemy/__init__.py", line 552, in __get__
return type.query_class(mapper, session=self.sa.session())
File "/XXX/flaskthreading/venv/lib/python3.9/site-packages/sqlalchemy/orm/scoping.py", line 47, in __call__
sess = self.registry()
File "/XXX/flaskthreading/venv/lib/python3.9/site-packages/sqlalchemy/util/_collections.py", line 1010, in __call__
return self.registry.setdefault(key, self.createfunc())
File "/XXX/flaskthreading/venv/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 4225, in __call__
return self.class_(**local_kw)
File "/XXX/flaskthreading/venv/lib/python3.9/site-packages/flask_sqlalchemy/__init__.py", line 174, in __init__
self.app = app = db.get_app()
File "/XXX/flaskthreading/venv/lib/python3.9/site-packages/flask_sqlalchemy/__init__.py", line 1042, in get_app
raise RuntimeError(
RuntimeError: No application found. Either work inside a view function or push an application context. See http://flask-sqlalchemy.pocoo.org/contexts/.
Run Code Online (Sandbox Code Playgroud)
知道为什么会发生这种情况或者我们错过了哪些文档吗?MVP 提供https://github.com/bodik/flaskthreading-experiments/
git clone
pip install -r requirements.txt
# working app
FLASK_APP=app1 flask run
curl http://localhost:5000/
# produces error
FLASK_APP=app2.app flask run
curl http://localhost:5000/
Run Code Online (Sandbox Code Playgroud)
来自https://flask.palletsprojects.com/en/2.1.x/reqcontext/#lifetime-of-the-context:
当 Flask 应用程序开始处理请求时,它会推送请求上下文,该请求上下文也会推送应用程序上下文。当请求结束时,它会弹出请求上下文,然后弹出应用程序上下文。
每个线程(或其他工作类型)的上下文都是唯一的。...
app在全局性的情况下db = SQLAlchemy(app),db总是有的self.app。
对于应用程序工厂模式,db从线程获取应用程序上下文。
传递一个AppContext要推送到线程上的值:
# def printer(): # Change this
def printer(app_context): # to this
app_context.push() #
print(User.query.all())
@blueprint.route('/')
def index():
# athread = Thread(target=printer, args=(), daemon=True) # Change this
athread = Thread(target=printer, args=(current_app.app_context(),), daemon=True) # to this
athread.start()
return 'ok'
Run Code Online (Sandbox Code Playgroud)