简体   繁体   English

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

[英]How to set statement timeout for query execution

In my web app some postgres sql queries take along time for execution. 在我的网络应用程序中,一些postgres sql查询需要时间来执行。 I want set statement timeout for only part of them. 我想只为其中一部分设置语句超时。

One part of queries must canceled by timeout, but other must work without any restriction. 查询的一部分必须通过超时取消,但其他部分必须无任何限制地工作。

In postgres exist statement_timeout function. 在postgres中存在statement_timeout函数。

How to wrap SqlAlchemy query with statement_timeout function? 如何用statement_timeout函数包装SqlAlchemy查询?

Like this: 像这样:

SET statement_timeout TO 1000; -- timeout for one second
<sqlalchemy generated query>;
RESET statement_timeout; -- reset

Perfect way for me set timeout for query like this: 对我来说完美的方式设置查询超时,如下所示:

users = session.query(User).timeout(0.5).all()

SqlAlchemy must: 1) set statement timeout 2) execute query and return result 3) reset statement timeout for current session SqlAlchemy必须:1)设置语句超时2)执行查询并返回结果3)当前会话的重置语句超时

May be other way to set timeout for query execution? 可能是为查询执行设置超时的其他方法?

UPDATE 1. My solution 更新1.我的解决方案

My solution is a custom connection proxy (tested with psycopg2==2.4 and SQLAlchemy==0.6.6): 我的解决方案是自定义连接代理(使用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)

This solution without reseting statement_timeout, because each SqlAlchemy query executed in isolated transaction and statement_timeout defined inside current transaction. 此解决方案无需重置statement_timeout,因为每个SqlAlchemy查询都在隔离事务中执行,而statement_timeout在当前事务中定义。

Usage example (timeout pаram in seconds): 用法示例(以秒为单位的超时参数):

Session.query(Author).execution_options(timeout=0.001).all()

Session.bind.execute(text('select * from author;') \
      .execution_options(timeout=0.001)) \
      .fetchall()

You should look at the extensions provided with SQLAlchemy <= 0.6: 您应该查看SQLAlchemy <= 0.6提供的扩展:

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

There are hooks where you could stick in your code for individual operations. 有一些钩子,你可以在你的代码中坚持个人操作。

SQLAlchemy 0.7+ now has an event system...there might be something similar. SQLAlchemy 0.7+现在有一个事件系统......可能有类似的东西。 See 看到

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM