gpt4 book ai didi

python - 使用 Celery worker 与 SQLAlchemy DB 交互,包括从请求中了解用户

转载 作者:行者123 更新时间:2023-11-28 20:56:18 26 4
gpt4 key购买 nike

我对此进行了大量研究,包括尝试像 this 这样的答案. Celery 似乎无法访问我的 Flask 应用程序的上下文。

我非常了解我的 celery 对象,它将装饰我的任务,必须能够访问我的 Flask 应用程序的上下文。我确实相信它应该,因为我遵循了 this创建我的 celery 对象的指南。我不确定混淆是否在于我使用 Flask-HTTPAuth 的事实。

这是我的一些东西。

def make_celery(app):
celery = Celery(app.import_name, backend=app.config["CELERY_RESULT_BACKEND"], broker=app.config["CELERY_BROKER_URL"])
celery.conf.update(app.config)
TaskBase = celery.Task
class ContextTask(TaskBase):
abstract = True
def __call__(self, *args, **kwargs):
with app.app_context():
return TaskBase.__call__(self, *args, **kwargs)
celery.Task = ContextTask
return celery

app = Flask(__name__)
auth = HTTPBasicAuth()
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///flask_app.db"
app.config["CELERY_BROKER_URL"] = "redis://localhost:6379"
app.config["CELERY_RESULT_BACKEND"] = "redis://localhost:6379"
celery = make_celery(app)
db = SQLAlchemy(app)

@celery.task(bind=True, name="flask_app.item_loop")
def loop(self):
items = g.user.items
for item in items:
print(item)

不过,使用 Flask 运行此任务是不行的。我尝试通过点击服务器(在授权的情况下!)来启动此功能。

@app.route("/item_loop")
@auth.login_required
def item_loop():
result = loop.delay()
return "It's running."

但是 Celery worker 告诉我任务 raised unexpected: AttributeError("'_AppCtxGlobals' object has no attribute 'user'",),如前所述,我相信这意味着我的 celery 对象没有应用上下文,即使我使用了推荐的工厂模式。

最佳答案

虽然 Dave 和 Greg 的回答中的推荐是有效的,但他们没有强调的是您对在 Celery 任务中使用应用程序上下文存在误解。

您有一个 Flask 应用程序,您在其中使用 Flask-HTTPAuth。您可能有一个 verify_password 处理程序,它将 g.user 设置为经过身份验证的用户。这意味着当您处理请求时,您可以作为 g.user 访问用户。这一切都很好。

您还有一个或多个 Celery worker,它们是独立的进程,与 Flask 服务器没有直接连接。 Flask 服务器和 Celery 工作进程之间的唯一通信发生在您使用的消息代理(通常是 Redis 或 RabbitMQ)上。

根据您的需要,Celery 工作人员可能需要访问 Flask 应用程序。这在使用将配置存储在 app.config 字典中的 Flask 扩展时非常常见。需要这个的两个常见扩展是 Flask-SQLAlchemy 和 Flask-Mail。如果无法访问 app.config,Celery 任务将无法打开与数据库的连接或发送电子邮件,因为它不知道数据库和/或电子邮件服务器的详细信息。

为了让 Celery 工作人员能够访问配置,公认的做法是在每个工作人员中创建重复的 Flask 应用程序。这些是辅助应用程序,它们与主 Flask 服务器使用的实际应用程序对象没有任何联系。它们的唯一目的是保存原始 app.config 字典的副本,您的任务或您的任务正在使用的任何 Flask 扩展都可以访问该字典。

因此,期望在 Flask 服务器中设置的 g.user 在 Celery 任务中也可以作为 g.user 访问是无效的,因为它们是来自不同应用程序实例的不同 g 对象。

如果你需要在 Celery 任务中使用经过身份验证的用户,你应该做的是将 user_id(通常是 g.user.id)作为参数传递给你的任务。然后在您的任务中,您可以使用此 id 从数据库加载用户。希望这对您有所帮助!

关于python - 使用 Celery worker 与 SQLAlchemy DB 交互,包括从请求中了解用户,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54836672/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com