python - tutorial - sqlalchemy create database if not exists postgres
Cómo establecer el tiempo de espera de la instrucción para la ejecución de consultas (1)
En mi aplicación web, algunas consultas de Postgres sql llevan tiempo para la ejecución. Quiero establecer el tiempo de espera de la declaración sólo para una parte de ellos.
Una parte de las consultas debe cancelarse por tiempo de espera, pero la otra debe funcionar sin ninguna restricción.
En postgres existe la función statement_timeout.
¿Cómo envolver la consulta SqlAlchemy con la función statement_timeout?
Me gusta esto:
SET statement_timeout TO 1000; -- timeout for one second
<sqlalchemy generated query>;
RESET statement_timeout; -- reset
La forma perfecta para mí de establecer el tiempo de espera para una consulta como esta:
users = session.query(User).timeout(0.5).all()
SqlAlchemy debe: 1) establecer el tiempo de espera de la declaración 2) ejecutar la consulta y devolver el resultado 3) restablecer el tiempo de espera de la instrucción para la sesión actual
¿Puede ser otra forma de establecer el tiempo de espera para la ejecución de consultas?
ACTUALIZACIÓN 1. Mi solución
Mi solución es un proxy de conexión personalizado (probado con psycopg2 == 2.4 y 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)
Esta solución sin restablecer statement_timeout, porque cada consulta SqlAlchemy se ejecuta en una transacción aislada y statement_timeout definido dentro de la transacción actual
Ejemplo de uso (tiempo de espera en segundos):
Session.query(Author).execution_options(timeout=0.001).all()
Session.bind.execute(text(''select * from author;'') /
.execution_options(timeout=0.001)) /
.fetchall()
Debes mirar las extensiones provistas con SQLAlchemy <= 0.6:
http://www.sqlalchemy.org/docs/06/orm/interfaces.html
Hay ganchos donde podría pegar en su código para operaciones individuales.
SQLAlchemy 0.7+ ahora tiene un sistema de eventos ... puede haber algo similar. Ver