68 lines
2.5 KiB
Python
68 lines
2.5 KiB
Python
"""Declarative table specs for ``CachingEngine(tables=[...])``.
|
|
|
|
Instead of the lazy "learn columns from queries" mode, an application can declare
|
|
each table up front — its columns, indexes, refresh strategy and datetime columns —
|
|
so the engine preloads them and rejects anything undeclared (fail-fast) rather than
|
|
silently triggering an expensive lazy load. The legacy ``delta=/ttl=/indexes=``
|
|
kwargs keep working; ``tables=`` is converted to the same internal config.
|
|
"""
|
|
|
|
from dataclasses import dataclass, field
|
|
|
|
from .delta import DeltaConfig
|
|
from .schedule import ScheduleSpec, parse_schedule
|
|
|
|
# Friendly alias for the declarative API; ``Delta`` and ``DeltaConfig`` are the
|
|
# same type (``change_column`` + ``key_columns``), so either may be used as a
|
|
# ``TableSpec.refresh`` strategy.
|
|
Delta = DeltaConfig
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class TTL:
|
|
"""Time-based refresh strategy: full-reload the table when older than *seconds*."""
|
|
|
|
seconds: int
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class Schedule:
|
|
"""Time-of-day refresh strategy: full-reload the table at fixed times of day.
|
|
|
|
*times* is one time of day or a list of them (``"HH:MM"``/``"HH:MM:SS"``
|
|
strings or :class:`datetime.time`), interpreted in the local timezone.
|
|
Validated eagerly so a typo surfaces at construction, not at the first
|
|
refresh tick.
|
|
"""
|
|
|
|
times: ScheduleSpec
|
|
|
|
def __post_init__(self) -> None:
|
|
parse_schedule("<Schedule>", self.times) # eager validation; table name unknown yet
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class TableSpec:
|
|
"""Declarative specification of one cached table.
|
|
|
|
*columns* lists the columns to cache; leave it ``None`` to cache the whole
|
|
table (``SELECT *`` semantics) and allow any column. When columns are listed,
|
|
a query asking for a column outside the list raises
|
|
:class:`~sqlmem.exceptions.UndeclaredError`.
|
|
|
|
*refresh* is a :class:`Delta` (change-column incremental sync), :class:`TTL`
|
|
(time-based full reload) or :class:`Schedule` (full reload at fixed times of
|
|
day), or ``None`` for a static table loaded once.
|
|
|
|
*preload=True* loads the table at startup (in the background by default) so the
|
|
first query is a cache hit instead of paying a cold load; a copy already fresh
|
|
in the persistent cache is skipped.
|
|
"""
|
|
|
|
name: str
|
|
columns: list[str] | None = None
|
|
indexes: list[str | list[str]] = field(default_factory=list)
|
|
refresh: DeltaConfig | TTL | Schedule | None = None
|
|
datetime_columns: list[str] = field(default_factory=list)
|
|
preload: bool = False
|