Flask,将 Flask-sqlalchemy 的应用程序上下文推送给 huey worker
Flask, push application context for Flask-sqlalchemy to huey worker
我是 python 生态系统和网络开发的新手,我想用 Flask 框架构建一个应用程序。
此应用程序必须执行后台任务。为此,我选择使用 huey 任务队列。
后台任务必须对数据库执行一些查询。为此,我选择了 Flask-SQLAlchemy.
我成功地在 huey 工人上执行了我的任务:
NFO:huey.consumer:MainThread:The following commands are available:
+ app.tasks.my_task
INFO:huey:Worker-1:Executing app.tasks.my_task: c5dd18bc-df2e-4380-9c1f-b597d2924ba2
但是出现如下错误:
/huey/api.py", line 379, in _execute task_value = task.execute()
...
...
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/.
这是我的项目结构:
app/
├── config.py
├── __init__.py
├── models.py
├── tasks.py
├── views.py
└─── foo.db
这是我的代码:
#__init__.py
from flask import Flask
from app.config import db, Config, huey
from app.tasks import my_task
def create_app():
app = Flask(__name__)
app.config.from_object(Config)
db.init_app(app)
# register blueprints
from app.views import main as main_blueprint
app.register_blueprint(main_blueprint)
return app
#config.py
from flask_sqlalchemy import SQLAlchemy
from huey import RedisHuey
huey = RedisHuey(__name__, host="localhost")
db = SQLAlchemy()
class Config:
SQLALCHEMY_DATABASE_URI = "sqlite:///foo.db"
SQLALCHEMY_TRACK_MODIFICATIONS = False
#tasks.py
from app.config import huey
from app.models import User
@huey.task()
#@huey.context_task(??)
def background_task():
print("Database query:")
User.query.get(1) # Here is the problem
return 1
#view.py
from flask import Blueprint
from app.tasks import my_task
main = Blueprint("main", __name__)
@main.route("/")
def index():
background_task() # running the registered background task
return "hello view"
#models.py
from app.config import db
class User(db.Model):
def __init__(self, username: str):
self.username = username
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(64), unique=True, nullable=False)
我浏览了 flask 应用程序上下文文档:
https://flask.palletsprojects.com/en/2.1.x/appcontext/
还有关于分片资源的 huey 文档:
https://huey.readthedocs.io/en/latest/shared_resources.html
我知道我必须以某种方式向工作人员提供应用程序上下文,但我无法将各个部分连接在一起。
我也试过这个
from flask import current_app
@huey.task()
def my_task():
with current_app.app_context():
print("Database query:")
User.query.get(1)
return 1
它给了我这个错误:
/flask/globals.py", line 47, in _find_app raise RuntimeError(_app_ctx_err_msg)
RuntimeError: Working outside of application context.
最好让 Huey 创建一个 Flask 应用程序供其使用。按如下方式组织代码:
添加第二种创建 Flask 应用供 Huey 特定使用的方法,类似于 create_app
#__init__.py
from flask import Flask
from app.config import db, Config, huey
from app.tasks import my_task
def create_app():
# ...
return app
def create_huey_app():
app = Flask('HUEY APP')
app.config.from_object(Config)
# only initialize stuff here that is needed by Huey, eg DB connection
db.init_app(app)
# register any blueprints needed
# e.g. maybe it needs a blueprint to work with urls in email generation
return app
让你所有的任务都有一个可调用的第一个参数:
#tasks.py
from app.config import huey
from app.models import User
# every task takes an app_factory parameter
@huey.task()
def background_task(app_factory):
app = app_factory()
with app.app_context():
User.query.get(1)
return 1
然后将create_huey_app
作为可调用对象传递给每个任务实例化:
#view.py
from flask import Blueprint
from app.tasks import my_task
main = Blueprint("main", __name__)
@main.route("/")
def index():
# pass the Huey app factory to the task
background_task(create_huey_app) # running the registered background task
return "hello view"
如果你想在调试时在本地运行任务:
@main.route("/")
def index():
# pass the Huey app factory to the task
if current_app.debug:
background_task.call_local(create_huey_app) # running the task directly
else:
background_task(create_huey_app) # running the task in Huey
return "hello view"
我是 python 生态系统和网络开发的新手,我想用 Flask 框架构建一个应用程序。
此应用程序必须执行后台任务。为此,我选择使用 huey 任务队列。
后台任务必须对数据库执行一些查询。为此,我选择了 Flask-SQLAlchemy.
我成功地在 huey 工人上执行了我的任务:
NFO:huey.consumer:MainThread:The following commands are available:
+ app.tasks.my_task
INFO:huey:Worker-1:Executing app.tasks.my_task: c5dd18bc-df2e-4380-9c1f-b597d2924ba2
但是出现如下错误:
/huey/api.py", line 379, in _execute task_value = task.execute()
...
...
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/.
这是我的项目结构:
app/
├── config.py
├── __init__.py
├── models.py
├── tasks.py
├── views.py
└─── foo.db
这是我的代码:
#__init__.py
from flask import Flask
from app.config import db, Config, huey
from app.tasks import my_task
def create_app():
app = Flask(__name__)
app.config.from_object(Config)
db.init_app(app)
# register blueprints
from app.views import main as main_blueprint
app.register_blueprint(main_blueprint)
return app
#config.py
from flask_sqlalchemy import SQLAlchemy
from huey import RedisHuey
huey = RedisHuey(__name__, host="localhost")
db = SQLAlchemy()
class Config:
SQLALCHEMY_DATABASE_URI = "sqlite:///foo.db"
SQLALCHEMY_TRACK_MODIFICATIONS = False
#tasks.py
from app.config import huey
from app.models import User
@huey.task()
#@huey.context_task(??)
def background_task():
print("Database query:")
User.query.get(1) # Here is the problem
return 1
#view.py
from flask import Blueprint
from app.tasks import my_task
main = Blueprint("main", __name__)
@main.route("/")
def index():
background_task() # running the registered background task
return "hello view"
#models.py
from app.config import db
class User(db.Model):
def __init__(self, username: str):
self.username = username
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(64), unique=True, nullable=False)
我浏览了 flask 应用程序上下文文档:
https://flask.palletsprojects.com/en/2.1.x/appcontext/
还有关于分片资源的 huey 文档:
https://huey.readthedocs.io/en/latest/shared_resources.html
我知道我必须以某种方式向工作人员提供应用程序上下文,但我无法将各个部分连接在一起。
我也试过这个
from flask import current_app
@huey.task()
def my_task():
with current_app.app_context():
print("Database query:")
User.query.get(1)
return 1
它给了我这个错误:
/flask/globals.py", line 47, in _find_app raise RuntimeError(_app_ctx_err_msg)
RuntimeError: Working outside of application context.
最好让 Huey 创建一个 Flask 应用程序供其使用。按如下方式组织代码:
添加第二种创建 Flask 应用供 Huey 特定使用的方法,类似于 create_app
#__init__.py
from flask import Flask
from app.config import db, Config, huey
from app.tasks import my_task
def create_app():
# ...
return app
def create_huey_app():
app = Flask('HUEY APP')
app.config.from_object(Config)
# only initialize stuff here that is needed by Huey, eg DB connection
db.init_app(app)
# register any blueprints needed
# e.g. maybe it needs a blueprint to work with urls in email generation
return app
让你所有的任务都有一个可调用的第一个参数:
#tasks.py
from app.config import huey
from app.models import User
# every task takes an app_factory parameter
@huey.task()
def background_task(app_factory):
app = app_factory()
with app.app_context():
User.query.get(1)
return 1
然后将create_huey_app
作为可调用对象传递给每个任务实例化:
#view.py
from flask import Blueprint
from app.tasks import my_task
main = Blueprint("main", __name__)
@main.route("/")
def index():
# pass the Huey app factory to the task
background_task(create_huey_app) # running the registered background task
return "hello view"
如果你想在调试时在本地运行任务:
@main.route("/")
def index():
# pass the Huey app factory to the task
if current_app.debug:
background_task.call_local(create_huey_app) # running the task directly
else:
background_task(create_huey_app) # running the task in Huey
return "hello view"