SQLAlchemy数据在连接

时间:2017-01-03 17:08:41

标签: sqlite sqlalchemy python-asyncio isolation-level flask-restful

我有几个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

1 个答案:

答案 0 :(得分:1)

SQLAlchemy默认情况下不提交更改,直到处理程序退出,您需要显式调用session.commit()

但是,使用来自异步协同程序的同步SQLAlchemy代码,即使在相对适度的负载下也能有效地杀死性能