繁体   English   中英

Flask,将 Flask-sqlalchemy 的应用程序上下文推送到 huey worker

[英]Flask, push application context for Flask-sqlalchemy to huey worker

我是 python 生态系统和 Web 开发的新手,我想用Flask框架构建一个应用程序。

此应用程序必须执行后台任务。 为此,我选择使用Huey任务队列。

后台任务必须对数据库执行一些查询。 为此,我选择了Flask-SQLAlchemy

我设法在休伊工人身上执行了我的任务:

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)

我浏览了烧瓶应用程序上下文文档:

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 应用程序供其使用。 按如下方式组织您的代码:

添加第二种方法,为 Huey 的特定用途创建一个 Flask 应用程序,类似于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"    

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM