在我的Web应用程序中,一些postgres sql查询需要一些时间才能执行。我只想为其中一部分设置语句超时。
查询的一部分必须通过超时取消,但是其他部分必须可以不受任何限制地工作。
在postgres中存在statement_timeout函数。
如何使用statement_timeout函数包装SqlAlchemy查询?
像这样:
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()
您应该查看SQLAlchemy <= 0.6提供的扩展:
http://www.sqlalchemy.org/docs/06/orm/interfaces.html
您可以在钩子中粘贴代码以进行单个操作。
SQLAlchemy 0.7+现在有一个事件系统…可能有类似的东西。看到
http://www.sqlalchemy.org/docs/core/events.html