web-dev-qa-db-ja.com

psycopg2でtransaction \ queryタイムアウトを設定しますか?

データベーストランザクションまたはデータベースクエリの psycopg2 にタイムアウトを設定する方法はありますか?

サンプルのユースケース:
HerokuはDjango Webリクエストを30秒に制限します。その後、HerokuはDjangoがないトランザクションを正常にロールバックすることを許可せずに、リクエストを終了しますこれにより、postgresで未処理のトランザクションが開いたままになる可能性があります。データベースでタイムアウトを構成できますが、メンテナンススクリプト分析などのWeb関連以外のクエリも制限されます。この場合、ミドルウェアを介してタイムアウトを設定します(- またはDjango経由 )が望ましいでしょう。

17
Jonathan

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

SQLを使用して、ステートメントごとのタイムアウトをいつでも設定できます。例えば:

SET statement_timeout = '2s'

2秒以上かかるステートメント(それに続く)を中止します(有効な単位は「s」または「ms」として使用できます)。ステートメントがタイムアウトすると、psycopgは例外を発生させるので、それをキャッチして適切に動作するように注意してください。

8
fog

PostgreSQL9.6がアイドルトランザクションタイムアウトを追加したようです。見る:

PostgreSQL 9.6はHerokuでもサポートされているため、これを使用できるはずです。

1
Tuukka Mustonen