Skip to main content
 首页 » 编程设计

python之Heroku 上的 Flask 和 Celery : sqlalchemy. exc.DatabaseError : (psycopg2. DatabaseError) SSL 错误:解密失败或错误记录 mac

2025年05月04日14Free-Thinker

我正在尝试在 heroku 上部署一个 flask 应用程序,该应用程序在 Celery 中使用后台任务。我已经实现了 application factory pattern这样 celery 进程就不会绑定(bind)到 flask 应用程序的任何一个实例。

这在本地有效,我还没有看到错误。但是当部署到 heroku 时,总是会出现相同的结果:celery 任务(我只使用一个)在第一次运行时成功,但是对该任务的任何后续 celery 调用都会失败并出现 sqlalchemy.exc.DatabaseError: (psycopg2.DatabaseError) SSL 错误:解密失败或错误记录 mac。如果我重新启动 celery worker,循环将继续。

有multiple issues显示相同的 error ,但没有指定适当的解决方案。我最初认为实现应用程序工厂模式可以防止出现此错误,但事实并非如此。

在 app/__init__.py 我创建了 celery 和 db 对象:

celery = Celery(__name__, broker=Config.CELERY_BROKER_URL) 
db = SQLAlchemy() 
 
def create_app(config_name): 
    app = Flask(__name__) 
    app.config.from_object(config[config_name]) 
 
    db.init_app(app) 
    return app 

我的 flask_celery.py 文件创建了实际的 Flask 应用程序对象:

import os 
from app import celery, create_app 
 
app = create_app(os.getenv('FLASK_CONFIG', 'default')) 
app.app_context().push() 

我用这个命令启动 celery : celery worker -A app.flask_celery.celery --loglevel=info

实际的 celery 任务是这样的:

@celery.task() 
def task_process_stuff(stuff_id): 
    stuff = Stuff.query.get(stuff_id) 
    stuff.processed = True 
    db.session.add(stuff) 
    db.session.commit() 
    return stuff 

调用者:

task_process_stuff.apply_async(args=[stuff.id], countdown=10) 

库版本

  • flask 0.12.2
  • SQLAlchemy 1.1.11
  • Flask-SQLAlchemy 2.2
  • celery 4.0.2

请您参考如下方法:

解决方案是在任务的开头添加 db.engine.dispose(),在任何工作开始之前处理所有数据库连接:

@celery.task() 
def task_process_stuff(stuff_id): 
    db.engine.dispose() 
    stuff = Stuff.query.get(stuff_id) 
    stuff.processed = True 
    db.session.commit() 
    return stuff 

因为我的所有任务都需要这个功能,所以我将它添加到 task_prerun:

@task_prerun.connect 
def on_task_init(*args, **kwargs): 
    db.engine.dispose()