我有一个使用Flask RESTful以及Flask SQLAlchemy的python应用。我编写的API的一部分具有旋转Timer对象的副作用。当Timer
到期时,它会执行一些数据库查询。我发现一个问题,即应该更新数据库中的行(sqlite后端)的代码实际上没有发出任何UPDATE
语句。我已通过打开SQLALCHEMY_ECHO
标志来记录SQL语句来验证这一点。代码是否有效似乎是随机的。大约一半的时间未能发出UPDATE
声明。请参阅下面的完整示例。
我的猜测是,当从工作线程调用时,SQLAlchemy Flask无法正常工作。我认为Flask SQLAlchemy的部分要点是根据API请求为您管理SQLAlchemy会话。显然,由于Timer
到期时没有API请求,我可以看到事情可能无法正常工作。
为了测试这个,我继续使用python' s 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()
答案 0 :(得分:0)
我猜你的回调你实际上并没有改变对象的价值。如果会话状态不脏,SQLAlchemey不会发出DB UPDATE调用。因此,如果由于某种原因相位已经为1,那么就无所事事了。