【问题标题】:Using Flask SQLAlchemy from worker threads从工作线程中使用 Flask SQLAlchemy
【发布时间】:2017-01-10 23:06:09
【问题描述】:

我有一个使用Flask RESTfulFlask SQLAlchemy 的python 应用程序。我正在编写的 API 的一部分具有分离 Timer 对象的副作用。当Timer 过期时,它会执行一些数据库查询。我看到一个问题,其中应该更新数据库中的行(sqlite 后端)的代码实际上没有发出任何 UPDATE 语句。我已经通过打开SQLALCHEMY_ECHO 标志来记录SQL 语句来验证这一点。代码是否有效似乎是随机的。大约有一半的时间它没有发出UPDATE 声明。请参阅下面的完整示例。

我的猜测是 SQLAlchemy Flask 在从工作线程调用时无法正常工作。我认为 Flask SQLAlchemy 的部分重点是根据 API 请求为您管理 SQLAlchemy 会话。显然,由于Timer 过期时没有 API 请求进行,我可以看到可能无法正常工作的地方。

为了测试这个,我继续使用python的sqlite3 interface写了一个简单的数据访问层,它似乎解决了这个问题。

不过,我真的不想重写一堆数据访问代码。在这种情况下,有没有办法让 Flask SQLAlchemy 正常工作?

示例代码

这是我设置烧瓶应用程序并保存 SQLAlchemy db 对象的地方:

from flask import Flask
from flask_restful import Api
from flask.ext.sqlalchemy import SQLAlchemy
from flask_cors import CORS
import db_conn

flask_app = Flask(__name__)
flask_app.config.from_object('config')
CORS(flask_app)
api = Api(flask_app)
db_conn.db = SQLAlchemy(flask_app)

api.add_resource(SomeClass, '/abc/<some_id>/def')

以下是我创建 ORM 模型的方法:

import db_conn

db = db_conn.db

class MyTable(db.Model):
    __tablename__ = 'my_table'
    id = db.Column(db.Integer, primary_key=True)
    phase = db.Column(db.Integer, nullable=False, default=0)

    def set_phase(self, phase):
        self.phase = phase
        db.session.commit()

这是带有计时器的 API 处理程序和失败的数据库调用:

from flask_restful import Resource
from threading import Timer
from models import MyTable
import db_conn
import global_store

class SomeClass(Resource):    
    def put(self, some_id):
        global_store.saved_id = some_id
        self.timer = Timer(60, self.callback)
        return '', 204

    def callback(self):
        row = MyTable.query.filter_by(id=global_store.saved_id).one()
        
        # sometimes this works, sometimes it doesn't
        row.set_phase(1)
        db_conn.db.session.commit()

【问题讨论】:

  • 此示例看起来不完整,您没有向 sqlalchemy 会话添加任何内容。您能否发布一个执行查询然后尝试执行更新的示例?
  • @snowballhg 好的,我继续添加更多细节。

标签: python database multithreading flask-sqlalchemy flask-restful


【解决方案1】:

我猜在你的回调中你实际上并没有改变对象的值。如果会话状态不脏,SQLAlchemey 不会发出 DB UPDATE 调用。因此,如果由于某种原因相位已经为 1,则无事可做。

【讨论】:

    猜你喜欢
    • 2022-01-14
    • 2016-12-04
    • 1970-01-01
    • 2021-10-17
    • 1970-01-01
    • 2021-06-26
    • 2011-01-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多