有没有办法在psycopg2中为数据库事务或数据库查询设置超时?
一个示例用例:
Heroku 将 django Web 请求限制为 30 秒,之后 Heroku 终止请求,不允许 django 优雅地回滚任何尚未返回的事务。这可能会使未完成的事务在 postgres 上处于打开状态。您可以在数据库中配置超时,但这也会限制与 Web 无关的查询,例如维护脚本分析等。在这种情况下,最好通过中间件(或通过 django)设置超时。
有没有办法在psycopg2中为数据库事务或数据库查询设置超时?
一个示例用例:
Heroku 将 django Web 请求限制为 30 秒,之后 Heroku 终止请求,不允许 django 优雅地回滚任何尚未返回的事务。这可能会使未完成的事务在 postgres 上处于打开状态。您可以在数据库中配置超时,但这也会限制与 Web 无关的查询,例如维护脚本分析等。在这种情况下,最好通过中间件(或通过 django)设置超时。
您可以使用 options 参数在连接时设置超时。语法有点奇怪:
>>> import psycopg2
>>> cnn = psycopg2.connect("dbname=test options='-c statement_timeout=1000'")
>>> cur = cnn.cursor()
>>> cur.execute("select pg_sleep(2000)")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
psycopg2.extensions.QueryCanceledError: canceling statement due to statement timeout
也可以使用 env 变量进行设置:
>>> import os
>>> os.environ['PGOPTIONS'] = '-c statement_timeout=1000'
>>> import psycopg2
>>> cnn = psycopg2.connect("dbname=test")
>>> cur = cnn.cursor()
>>> cur.execute("select pg_sleep(2000)")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
psycopg2.extensions.QueryCanceledError: canceling statement due to statement timeout
您可以随时使用 SQL 设置每个语句的超时。例如:
SET statement_timeout = '2s'
将中止任何花费超过 2 秒的语句(跟随它)(您可以使用任何有效的单位作为 's' 或 'ms')。请注意,当语句超时时,psycopg 会引发异常,您需要注意捕捉它并采取适当的行动。
看起来 PostgreSQL 9.6 添加了空闲事务超时。看:
Heroku 也支持 PostgreSQL 9.6,所以你应该可以使用它。