первая ссылка не работает
м веб-приложении некоторые 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()