2013-11-07 2 views
3

Контекст: Я работаю над флеш-приложением, работающим на CherryPy, DB обрабатывается с использованием SQLAlchemy ORM.Как обрабатывать несколько запросов без SQLAlchemy сбой/повышение исключений?

Проблема:

приложение прекрасно работает и делает все, что я хочу, однако, если у меня есть страница, которая извлекает некоторые данные из БД и дисплеев, и я нажмите и удерживайте «Ctrl + R» или " F5" . То есть, постоянно обновлять страницу, делая так много запросов БД. Первые несколько идут хорошо, а затем ломаются. Следующие ошибки регистрируются:

(OperationalError) (2013, 'Lost connection to MySQL server during query') 

Can't reconnect until invalid transaction is rolled back (original cause: 
InvalidRequestError: Can't reconnect until invalid transaction is rolled back) 

This result object does not return rows. It has been closed automatically. 

(ProgrammingError) (2014, "Commands out of sync; you can't run this command now") 

Там же еще одна ошибка, которая беспокоит меня (но не вошли в этот раз), это

dictionary changed size during iteration

Это происходит, когда я переборе запрос, используя значения, полученные для заполнения словаря. Словарь является локальным (область действия dict) для функции.

Подробнее:

Как я обработки сессий:

новый сеанс создается при вводе любой страницы, используйте эту сессию, чтобы выполнить все операции DB, и сессия закрыта правая перед рендерингом HTML. Технически это означает, что сфера сеанса такая же, как и HTTP-запрос.

Я делаю session.rollback() только при наличии исключения, вызванного во время таблицы updating или inserting в таблицу. Нет rollback() в течение любых query() операций. Я уверен, что я совершил глупые ошибки или не делаю правильных действий.

Неограниченное количество обновлений, как это не похоже на сценарий, но нельзя игнорировать. Кроме того, я думаю, что поведение будет схожим, когда много пользователей используют его одновременно.

Как двигатель SQLAlchemy, sessionmaker был обработан:

sql_alchemy_engine = create_engine(self.db_string, echo=False, encoding="utf8", convert_unicode=True, pool_recycle=9) 
sqla_session = sessionmaker(bind=sql_alchemy_engine) 

Это сделано только один раз, как это рекомендуется в документации SQLA, и новый сеанс создается и возвращается sqla_session() по мере необходимости.

ответ

3

Если вы используете Flask, вы должны использовать flask-sqlalchemy, и пусть контекст запроса флажка управляет вашей сессией и не обрабатывает ваш движок и сеансы вручную. Это как SQLAlchemy рекомендует его:

Большинство вебов-структуры включают в себя инфраструктуру для установления одной сессии, связанную с запросом, который правильно сконструированная и снесен соответствующим снесено в конце запроса. Такие компоненты инфраструктуры включают в себя такие продукты, как Flask-SQLAlchemy, для использования в сочетании с фреймворческой фреймворком и Zope-SQLAlchemy для использования в сочетании с платформами Pyramid и Zope. SQLAlchemy настоятельно рекомендует использовать эти продукты как доступные.

http://docs.sqlalchemy.org/en/rel_0_9/orm/session.html?highlight=flask

Затем вы создаете ваш двигатель просто:

from flask import Flask 
from flask.ext.sqlalchemy import SQLAlchemy 

app = Flask(__name__) 
app.config['SQLALCHEMY_DATABASE_URI'] = 'your db uri' 

db = SQLAlchemy(app) 

Или, если вы используете приложение завода:

from flask import Flask 
from flask.ext.sqlalchemy import SQLAlchemy 

db = SQLAlchemy() 

def create_app(): 
    app = Flask(__name__) 
    app.config['SQLALCHEMY_DATABASE_URI'] = 'your db uri' 

    db.init_app(app) 

При том, что базовая модель декларативного вы должны использовать это на db.Model, а сеанс, который вы должны использовать, будет находиться в db.session.

Смежные вопросы