Flask SQLAlchemy 和多处理

问题描述 投票:0回答:1

我有一个奇怪的问题,我想我设法缩小范围以使用 sqlalchemy 和多处理。

我正在使用 Flask、flask-sqlalchemy、pymysql 和 mysql 数据库。

我有一个 Flask 应用程序(models.py):

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask('appname')
db = SQLAlchemy(app)

然后我使用 Flask 使用多处理(app.py)从不同的 python 文件调用函数:

import multiprocessing
from models import app, db, TaskLog
from functions import do_stuff

@app.route('/some/address', methods=['GET'])
def start_process():
    process = multiprocessing.Process(target=do_stuff, args=(task_id, work_location))
    process.name = task_id
    process.start()
    return '', 200

@app.route('something/<task_id>/checklog', methods=['GET'])
def check_log(task_id):
    task_log = db.session.query(TaskLog).filter_by(task_id=task_id).all()
    return task_log

保存 do_stuff() 函数的另一个文件正在导入数据库(functions.py):

from models import app, db

# Do some stuff reading from and writing to the db

问题是什么:

有时我会遇到奇怪的错误,比如:

pymysql.err.OperationalError: (2013, 'Lost connection to MySQL server during query')

pymysql.err.InterfaceError: (0, '')

sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (2014, 'Command Out of Sync')

而且错误并不总是在同一个地方。有时它在执行数据库查询的线路上,而下次它在执行 db.session.commit() 等的线路上。奇怪的是,有时它可以正常工作几个小时,有时它会在随机位置出错。

我认为问题是我将 models.py 中声明的相同数据库导入到 app.py 和functions.py(作为多处理进程运行)。

你们能否确认这确实是问题所在,并建议如何使用 Flask-sqlalchemy 正确完成此操作?

任何帮助将不胜感激。

flask sqlalchemy multiprocessing flask-sqlalchemy pymysql
1个回答
0
投票

我并没有 100% 掌握多处理的速度,但认为这个调用会分叉你当前的进程及其中的所有内容。这可能会导致很多超出 sqlalchemy 范围的问题。对于 sqlalchemy,您可以尝试在 fork 之前和之后清理会话和引擎,以便 fork 和原始进程都有新鲜的东西,并且不会破坏原始的东西。将运行程序移至 cronjob 或任务队列可能会更容易。不过你可以试试这个:

分叉之前

这应该关闭所有当前事务并清除会话,以便可以再次重用。

db.session.close()

文档:闭幕会议

仅在子进程中分叉之后

可能可以在

target
中完成,这是假设您只有一个未命名为binds的绑定

db.engine.dispose(close=False)

我在上面提到了引擎的第二点:

文档:使用连接池和多处理或操作系统叉

© www.soinside.com 2019 - 2024. All rights reserved.