У меня есть несколько приложений python (отдельные процессы), которые используют Flask-SQLAlchemy для доступа к базе данных sqlite. Один из них настроен с использованием модуля asyncio (но все еще является флеш-приложением), а другой - Flask-RESTful API.Данные SQLAlchemy не согласованы между соединениями
Я вижу проблему, в которой данные, записанные в базу данных API-интерфейса Flask-RESTful, не видны приложению asyncio. Я читал, что это, вероятно, связано с уровнями изоляции (How to disable SQLAlchemy caching?). Если я использую session.expire_all()
, проблема исчезнет.
Так ли это из-за уровней изоляции? Я понимаю, что sqlite использует serializable isolation level почти все время (я считаю, что это в моем случае). API REST, который делает запись, совершает транзакции, но код асинхронного кода просто не видит их, если я не позвоню session.expire_all()
. Это похоже на проблему изоляции транзакций и больше похоже на проблему SQLAlchemy, но я не уверен на 100%.
Должен ли я всегда помнить, чтобы позвонить 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
Атрибут REST api вызывает 'session.commit()'. Вы говорите, что даже асинхронный код, который просто запрашивает данные, а не обновляет или вставляет что-либо, также нужно вызвать 'session.commit()'? – d512