我有一个 python 应用程序使用烧瓶宁静 http://flask-restful-cn.readthedocs.io/en/0.3.5也Flask SQLAlchemy http://flask-sqlalchemy.pocoo.org/2.1。我正在编写的部分 API 具有剥离的副作用Timer https://docs.python.org/2/library/threading.html#timer-objects对象。当一个Timer
过期后,它会执行一些数据库查询。我看到一个问题,其中应该更新数据库(sqlite 后端)中的行的代码实际上没有发出任何UPDATE
声明。我已经通过转动来验证了这一点SQLALCHEMY_ECHO
标记为记录 SQL 语句。代码是否有效似乎是随机的。大约有一半的时间它无法发出UPDATE
陈述。请参阅下面的完整示例。
我的猜测是,从工作线程调用时,SQLAlchemy Flask 无法正常工作。我认为 Flask SQLAlchemy 的部分目的是为每个 API 请求管理 SQLAlchemy 会话。显然,因为当Timer
过期后,我可以看到哪些地方可能无法正常工作。
为了测试这一点,我继续使用 python 编写了一个简单的数据访问层sqlite3接口 https://docs.python.org/2/library/sqlite3.html它似乎解决了问题。
不过,我真的不想重写一堆数据访问代码。在这种情况下,有没有办法让 Flask SQLAlchemy 正常工作?
示例代码
这是我设置 Flask 应用程序并保存 SQLAlchemy 的地方db
object:
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()