set transaction\query timeout in psycopg2?

2019-02-08 08:12发布

Is there a way to set a timeout in psycopg2 for db transactions or for db queries?

A sample use-case:
Heroku limits django web requests to 30sec, after which Heroku terminates the request without allowing django to gracefully roll-back any transactions which have not yet returned. This can leave outstanding transactions open on postgres. You could configure a timeout in the database, but that would also limit non-web-related queries such as maintenance scripts analytics etc. In this case setting a timeout via the middleware (or via django) would be preferable.

3条回答
我命由我不由天
2楼-- · 2019-02-08 08:30

Looks like PostgreSQL 9.6 added idle transaction timeouts. See:

PostgreSQL 9.6 is also supported in Heroku so you should be able to use this.

查看更多
走好不送
3楼-- · 2019-02-08 08:37

You can set a per-statement timeout at any time using SQL. For example:

SET statement_timeout = '2s'

will abort any statement (following it) that takes more than 2 seconds (you can use any valid unit as 's' or 'ms'). Note that when a statement timeouts, psycopg raises an exception and it is your care to catch it and act appropriately.

查看更多
聊天终结者
4楼-- · 2019-02-08 08:47

You can set the timeout at connection time using the options parameter. The syntax is a bit weird:

>>> 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

it can also be set using an env variable:

>>> 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
查看更多
登录 后发表回答