httk.store.db.engine

Database engine lifecycle: Database wraps a SQLAlchemy engine behind an httk-facing API.

A Database names where data lives — an SQLite file, an in-memory SQLite database, a DuckDB file — and owns the connection pool that reaches it. It deliberately exposes no SQL surface of its own: the store layer (SqlStore) asks it for connections internally, and user code only constructs one (usually via Database.sqlite() or Database.duckdb()) and passes it on. There is no global engine registry and no interpreter-exit hook; dispose of a database explicitly with Database.dispose() or use it as a context manager.

Classes

Database

A relational database reachable through a wrapped SQLAlchemy engine.

Module Contents

class httk.store.db.engine.Database(engine, *, degraded=False, write_profile=None)[source]

A relational database reachable through a wrapped SQLAlchemy engine.

Construct one with sqlite(), duckdb(), or clickhouse() (or, for other SQLAlchemy-supported backends, by passing a preconfigured engine directly). The instance is a context manager; leaving the with block disposes the engine’s connection pool.

Parameters:
  • engine (sqlalchemy.Engine) – The configured SQLAlchemy engine to wrap.

  • degraded (bool) – Open with autocommit isolation for degraded-mode access (recovery and inspection) instead of the default transactional isolation.

classmethod sqlite(path=None, *, degraded=False)[source]

Create an SQLite database stored in path, or in memory when path is None.

The in-memory variant is configured (via a static connection pool with a shared, thread-unrestricted connection) so that every connection drawn from the engine sees the one and same database; file-backed databases use SQLAlchemy’s default pooling.

Parameters:
  • path (str | os.PathLike[str] | None) – The database file path, or None for an in-memory database.

  • degraded (bool) – Open with autocommit isolation for degraded-mode access (recovery and inspection) instead of the default transactional isolation.

Returns:

The configured database wrapper.

Return type:

Self

classmethod duckdb(path=None, *, memory_limit=None)[source]

Create a DuckDB database stored in path, or in memory when path is None.

Parameters:
  • path (str | os.PathLike[str] | None) – The database file path, or None for an in-memory database.

  • memory_limit (str | None) – An optional DuckDB memory_limit setting such as "1GB". DuckDB’s own default allows every instance up to about 80% of system RAM, which multiplies dangerously across parallel test or ingest processes; when this parameter is None the HTTK_DUCKDB_MEMORY_LIMIT environment variable (if set) supplies the cap instead, so process trees can be memory-guarded wholesale.

Returns:

The configured database wrapper.

Raises:

ImportError – If the duckdb_engine SQLAlchemy dialect is not installed; install the httk-store[duckdb] extra to use it.

Return type:

Self

classmethod clickhouse(url, *, database=None)[source]

Create a ClickHouse database from a clickhousedb:// URL.

The URL uses the SQLAlchemy clickhouse-connect dialect, for example clickhousedb://default:@host:8123/my_database. database replaces the URL path when supplied. The constructor always merges join_use_nulls=1 into the URL query and selects the bulk-fenced storage profile before any SqlStore initialization occurs.

Raises:
  • ImportError – If clickhouse-connect is not installed; install the httk-store[clickhouse] extra.

  • RuntimeError – If Keeper is unavailable, the server is too old, or join_use_nulls cannot be enforced.

property degraded: bool[source]

Whether this wrapper deliberately uses the SQLite autocommit vehicle.

property write_profile: Literal['transactional', 'degraded', 'bulk-fenced'][source]

Return the profile selected before store initialization.

property server_version: str | None[source]

Return the server version captured at the first ClickHouse connection.

property lifecycle_generation: int[source]

Return the active lifecycle generation for guarded storage callbacks.

add_dispose_callback(callback, *, generation=None)[source]

Register a best-effort callback for the active lifecycle generation.

A disposed wrapper deliberately rejects late registration: accepting a callback after dispose() snapshots its callback list can strand a store-owned lease on a newly recreated pool.

lifecycle_guard(generation, *, holder=None)[source]

Prevent disposal while one named store mutation uses generation.

property engine: sqlalchemy.Engine[source]

Return the underlying SQLAlchemy engine for the storage layer.

Returns:

The wrapped SQLAlchemy engine.

Return type:

sqlalchemy.Engine

dispose()[source]

Dispose the current connection pool; later use creates a new pool.

Returns:

None.

Return type:

None