我有几个python应用程序(单独的进程)都使用Flask-SQLAlchemy来访问sqlite数据库。其中一个是使用asyncio模块设置的(但仍然是Flask应用),另一个是Flask-RESTful API。
我发现asyncio应用程序没有看到Flask-RESTful API写入数据库的数据。我读过这可能是由于隔离级别(How to disable SQLAlchemy caching?)。如果我使用session.expire_all()
,问题就会消失。
这真的是由于隔离级别吗?我的理解是sqlite几乎一直使用serializable isolation level(我相信这是我的情况)。正在进行编写的REST API正在提交其事务,但除非我调用session.expire_all()
,否则asyncio代码看不到它们。这似乎就像一个事务隔离问题,更像是一个SQLAlchemy问题,但我并不是百分百肯定。
我是否必须始终记得在查询数据库之前调用session.expire_all()
?有没有更好的方法来保持应用程序之间的一致性?
以下是一些有用的代码:
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
app = Flask(__name__)
db = SQLAlchemy(app)
@asyncio.coroutine
def grab_data_off_queue(self):
while True:
try:
hit = self.hit_queue.get(False)
# required for this session to see the changes made by REST api
db.session.expire_all()
rows = MyTable.query.filter_by.all()
for row in rows:
# the REST API is setting field_2 to 123,
# but this session cannot see those changes
if row.field_2 == 123:
do_something() #execution never gets here
以下是REST API:
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
app = Flask(__name__)
db = SQLAlchemy(app)
class MyApi(Resource):
def put(self, id):
row = MyTable.query.filter_by(table_id=id).one()
row.field_2 = 123
db.session.commit()
return '', 204
答案 0 :(得分:1)
SQLAlchemy
默认情况下不提交更改,直到处理程序退出,您需要显式调用session.commit()
。
但是,使用来自异步协同程序的同步SQLAlchemy
代码,即使在相对适度的负载下也能有效地杀死性能。