Как установить время ожидания оператора для выполнения запроса - PullRequest
23 голосов
/ 27 июня 2011

В моем веб-приложении некоторые sql-запросы postgres занимают много времени для выполнения.Я хочу установить тайм-аут оператора только для части из них.

Одна часть запросов должна быть отменена тайм-аутом, но другие должны работать без каких-либо ограничений.

В postgres существует функция Statement_timeout.

Как обернуть запрос SqlAlchemy с помощью оператора Statement_timeout?

Примерно так:

SET statement_timeout TO 1000; -- timeout for one second
<sqlalchemy generated query>;
RESET statement_timeout; -- reset

Идеальный способ для меня установить время ожидания для запроса следующим образом:

users = session.query(User).timeout(0.5).all()

SqlAlchemyдолжен: 1) установить время ожидания оператора 2) выполнить запрос и вернуть результат 3) сброс времени ожидания оператора для текущего сеанса

Может быть другой способ установить время ожидания для выполнения запроса?

ОБНОВЛЕНИЕ 1. Мое решение

Мое решение - настраиваемый прокси-сервер подключения (протестировано с psycopg2 == 2.4 и SQLAlchemy == 0.6.6):

from sqlalchemy.interfaces import ConnectionProxy

class TimeOutProxy(ConnectionProxy):
    def cursor_execute(self, execute, cursor, statement, parameters, context, executemany):

        timeout = context.execution_options.get('timeout', None)

        if timeout:
            c = cursor._parent.cursor()
            c.execute('SET statement_timeout TO %d;' % int(timeout * 1000))
            c.close()

        return execute(cursor, statement, parameters, context)


engine = create_engine(URL, proxy=TimeOutProxy(), pool_size=1, max_overflow=0)

Это решение без сброса Statement_timeout,потому что каждый запрос SqlAlchemy, выполненный в изолированной транзакции, и Statement_timeout, определенный внутри текущей транзакции.

Пример использования (время ожидания в секундах):

Session.query(Author).execution_options(timeout=0.001).all()

Session.bind.execute(text('select * from author;') \
      .execution_options(timeout=0.001)) \
      .fetchall()

1 Ответ

3 голосов
/ 27 июня 2011

Вам следует взглянуть на расширения, предоставляемые SQLAlchemy <= 0.6: </p>

http://www.sqlalchemy.org/docs/06/orm/interfaces.html

Существуют хуки, в которые вы можете вставить свой код для отдельных операций.

SQLAlchemy 0.7+ теперь имеет систему событий ... может быть что-то подобное. См

http://www.sqlalchemy.org/docs/core/events.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...