Timeouts

Provides the ability to set Postgres lock_timeout and statement_timeout values.

Note

Why use database timeouts?

Timeouts are a way of preventing queries / transactions running for too long.

Why are long-running queries a problem? It’s because they can block queries that change the database schema. These blocked migration queries, in turn, block subsequent queries as well, potentially causing an outage.

Function Definitions

timeouts.apply_timeouts(using: str, lock_timeout: datetime.timedelta | None = None, statement_timeout: datetime.timedelta | None = None, close_transaction_leak: bool = False) Iterator[None]:

A context manager to set Postgres timeouts.

Effectively executes the following SQL statements if in a transaction:

SET LOCAL lock_timeout '<lock_timeout>';

SET LOCAL statement_timeout '<lock_timeout>';

If not in a transaction, executes the following instead:

SET SESSION lock_timeout '<lock_timeout>';

SET SESSION statement_timeout '<lock_timeout>';

Parameters:
  • using (str) – Mandatory “using” database alias to use.

  • lock_timeout (datetime.timedelta | None) – Optional value to set “lock_timeout”.

  • statement_timeout (datetime.timedelta | None) – Optional value to set “statement_timeout”.

  • close_transaction_leak (bool = False) – Whether to close a leaky aborted transaction automatically.

Raises:
  • timeouts.TimeoutNotProvided – If neither lock nor statement timeouts are provided.

  • timeouts.TimeoutWasNotPositive – If either value of lock or statement timeout is negative.

  • timeouts.RedundantLockTimeout – When lock and statement timeouts are set to the same value. This is redundant because statement timeouts trump lock timeouts.

  • timeouts.CloseTransactionLeakInsideTransaction – When close_transaction_leak is True and running inside a transaction.

  • timeouts.DBLockTimeoutError – When the value of lock_timeout is reached during runtime.

  • timeouts.DBStatementTimeoutError – When the value of statement_timeout is reached during runtime.

  • timeouts.UnsupportedTimeoutBehaviour – Sentinel that is raised when a particular behaviour isn’t supported.

Returns:

yields the result.

Return type:

Iterator[None]

Example

import datetime
from django_pg_migration_tools import timeouts

with timeouts.apply_timeouts(
    using="default",
    lock_timeout=datetime.timedelta(seconds=10),
):
    # Code in this block will have a lock timeout of 10s.
    ...
    with timeouts.apply_timeouts(
        using="default",
        lock_timeout=datetime.timedelta(seconds=5),
    ):
        # Code inside this block will have a lock timeout of 5s.
        ...

    # We are back to the parent block, so lock timeout is 10s again.
    ...