buildgrid.server.sql.provider module

class buildgrid.server.sql.provider.SqlProvider(*, automigrate: bool = False, connection_string: str | None = None, connection_timeout: int = 5, lock_timeout: int = 5, connect_args: dict[Any, Any] | None = None, max_overflow: int | None = None, pool_pre_ping: bool | None = None, pool_recycle: int | None = None, pool_size: int | None = None, pool_timeout: int | None = None)

Bases: object

Class which provides an interface for interacting with an SQL database.

This class is used to allow configuration of a per-process SQL connection pool, which can then be shared across multiple components of BuildGrid which require an SQL connection.

Parameters:
  • automigrate (bool) – Whether or not to ensure the database is fully migrated when starting up. Defaults to False, meaning the database is assumed to be at the up to date already.

  • connection_string (str | None) – The connection string to use when creating a database connection. If None then a temporary SQLite database will be created for the lifetime of this object.

  • connection_timeout (int) – The timeout to use when attempting to connect to the database, in seconds. Defaults to 5 seconds if unset.

  • lock_timeout (int) – The timeout to use when the connection

  • database (holds a lock in the database. This is supported only if the) –

  • PostgresQL. (backend is) –

  • connect_args (dict[str, Any] | None) – Dictionary of DBAPI connection arguments to pass to the engine. See the SQLAlchemy docs for details.

  • max_overflow (int | None) – The number of connections to allow as “overflow” connections in the connection pool. This is the number of connections which will be able to be opened above the value of pool_size.

  • pool_pre_ping (bool | None) – Whether or not to test connections for liveness on checkout from the connection pool.

  • pool_recycle (int | None) – The number of seconds after which to recycle database connections. If None (the default) then connections won’t be recycled (the SQLAlchemy default value of -1 will be used).

  • pool_size (int | None) – The number of connections to keep open inside the engine’s connection pool.

  • pool_timeout (int | None) – The number of seconds to wait when attempting to get a connection from the connection pool.

Raises:

ValueError – when connection_string specifies an in-memory SQLite database.

property dialect: str

The SQL dialect in use by the configured SQL engine.

property default_inlimit: int

Return the default inlimit size based on the current SQL dialect

session(*, scoped: bool = False, sqlite_lock_immediately: bool = False, exceptions_to_not_raise_on: list[type[Exception]] | None = None, exceptions_to_not_rollback_on: list[type[Exception]] | None = None, expire_on_commit: bool = True) Iterator[Session]

ContextManager yielding an ORM Session for the configured database.

The sqlalchemy.orm.Session lives for the duration of the managed context, and any open transaction is committed upon exiting the context.

This method can potentially block for a short while before yielding if the underlying connection pool has recently been disposed of and refreshed due to connectivity issues.

When sqlite_lock_immediately is True, the Session will not yield until the database has been locked by entering into a write transaction when using SQLite.

If an Exception is raised whilst in the managed context, the ongoing database transaction is rolled back, and the Exception is reraised. Some Exceptions which suggest a transient connection issue with the database lead to a RetriableDatabaseError being raised from the Exception instead.

exceptions_to_not_raise_on defines a list of SQLAlchemyError types which should be suppressed instead of re-raised when occurring within the managed context.

Similarly, exceptions_to_not_rollback_on defines a list of SQLAlchemyError types which will not trigger a transaction rollback when occuring within the managed context. Instead, the open transaction will be committed and the session closed.

Parameters:
  • scoped – If true, use a scoped_session factory to create the session. This results in reuse of the underlying Session object in a given thread.

  • sqlite_lock_immediately – If true, execute a BEGIN IMMEDIATE statement as soon as the session is created when using SQLite. This allows locking for the lifetime of the Session within this ContextManager, enabling similar behaviour to SELECT ... FOR UPDATE in other dialects. Defaults to False.

  • exceptions_to_not_raise_on – The list of error types to be suppressed within the context rather than re-raised. Defaults to None, meaning all SQLAlchemyErrors will be re-raised.

  • exceptions_to_not_rollback_on – The list of error types which shouldn’t trigger a transaction rollback. Defaults to None, meaning all SQLAlchemyErrors will trigger rollback of the transaction.

  • expire_on_commit – Defaults to True. When True, all instances will be fully expired after each commit(), so that all attribute/object access subsequent to a completed transaction will load from the most recent database state. This flag is ignored if scoped == True

Yields:

A sqlalchemy.orm.Session object.

Raises:
  • DatabaseError – when a database session cannot be obtained.

  • RetriableDatabaseError – when the database connection is temporarily interrupted, but can be expected to recover.

  • Exception – Any Exception raised within the context will be re-raised unless it’s type is included in the exceptions_to_not_raise_on parameter.

scoped_session(*, sqlite_lock_immediately: bool = False, exceptions_to_not_raise_on: list[type[Exception]] | None = None, exceptions_to_not_rollback_on: list[type[Exception]] | None = None) Generator[Session, None, None]

ContextManager providing a thread-local ORM session for the database.

This is a shorthand for SqlProvider.session(scoped=True).

This ContextManager provides a reusable thread-local sqlalchemy.orm.Session object. Once the Session has been created by the initial call, subsequent calls to this method from within a given thread will return the same Session object until SqlProvider.remove_scoped_session() is called.

:param See SqlProvider.session() for further details.:

Yields:

A persistent thread-local sqlalchemy.orm.Session.

remove_scoped_session() None

Remove the thread-local session, if any.