如何为查询执行设置语句超时

Posted

技术标签:

【中文标题】如何为查询执行设置语句超时【英文标题】:How to set statement timeout for query execution 【发布时间】:2011-09-23 10:57:54 【问题描述】:

在我的网络应用程序中,一些 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()

【问题讨论】:

【参考方案1】:

您应该查看 SQLAlchemy

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

有一些钩子可以让您在代码中插入单独的操作。

SQLAlchemy 0.7+ 现在有一个事件系统...可能有类似的东西。见

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

【讨论】:

第一个链接坏了

以上是关于如何为查询执行设置语句超时的主要内容,如果未能解决你的问题,请参考以下文章

如何为 MFC 线程设置超时

如何为 liquibase 变更集设置超时?

雪花中的查询超时问题

如何为 AndroidAsync websockets 设置超时?

如何为 cassandra 设置读取请求超时

如何为 RabbitMQ RPC 请求设置超时?