postgresql 如何为查询执行设置语句超时
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6492366/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to set statement timeout for query execution
提问by estin
In my web app some postgres sql queries take along time for execution. I want set statement timeout for only part of them.
在我的 Web 应用程序中,一些 postgres sql 查询需要花费一些时间来执行。我只想为其中的一部分设置语句超时。
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()
采纳答案by Andreas Jung
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. See
SQLAlchemy 0.7+ 现在有一个事件系统......可能有类似的东西。看