Cómo establecer el tiempo de espera de la instrucción para la ejecución de consultas

En mi aplicación web, algunas consultas sql de postgres llevan tiempo para su ejecución. Quiero establecer el tiempo de espera de la declaración solo para una parte de ellos.

Una parte de las consultas debe cancelarse por tiempo de espera, pero 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

Manera perfecta para mí establecer tiempo de espera para consultas 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 declaración para la sesión actual

¿Puede ser otra forma de establecer el tiempo de espera para la ejecución de consultas?

UPDATE 1. Mi solució

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 reiniciar la declaración de tiempo de espera, porque cada consulta SqlAlchemy se ejecutó en una transacción aislada y la declaración de tiempo de espera 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()

Respuestas a la pregunta(1)

Su respuesta a la pregunta