Source code for loom.etl.declarative.expr._refs

"""Table and column references for the ETL declarative DSL."""

from __future__ import annotations

from loom.etl.declarative.expr._predicate import _ColOps


[docs] class TableRef: """Logical table identifier used by the ETL declarative DSL. Args: ref: Dotted logical table reference (for example ``"raw.orders"``). """ __slots__ = ("_ref",) def __init__(self, ref: str) -> None: self._ref = ref @property def ref(self) -> str: """Raw dotted table reference.""" return self._ref @property def c(self) -> _ColumnNamespace: """Column namespace for bound references.""" return _ColumnNamespace(self)
[docs] def qualify(self, default_catalog: str) -> TableRef: """Return a catalog-qualified reference when the ref is 2-part. If the ref already contains 3 parts (catalog.schema.table) or *default_catalog* is empty, the original reference is returned unchanged. Args: default_catalog: Catalog name to prepend when the ref is 2-part. Returns: New ``TableRef`` with catalog prefix, or self if already qualified. """ parts = self._ref.split(".") if len(parts) == 2 and default_catalog: return TableRef(f"{default_catalog}.{self._ref}") return self
def __eq__(self, other: object) -> bool: if not isinstance(other, TableRef): return NotImplemented return self._ref == other._ref def __hash__(self) -> int: return hash(self._ref) def __repr__(self) -> str: return f"TableRef({self._ref!r})"
class _ColumnNamespace: __slots__ = ("_table",) def __init__(self, table: TableRef) -> None: self._table = table def __getattr__(self, name: str) -> ColumnRef: if name.startswith("_"): raise AttributeError(name) return ColumnRef(table=self._table, name=name) class ColumnRef(_ColOps): """Column reference bound to a specific :class:`TableRef`.""" __slots__ = ("_table", "_name") def __init__(self, table: TableRef, name: str) -> None: self._table = table self._name = name @property def table(self) -> TableRef: """Table this column belongs to.""" return self._table @property def name(self) -> str: """Column name.""" return self._name def __hash__(self) -> int: return hash((self._table, self._name)) def __repr__(self) -> str: return f"{self._table.ref}.c.{self._name}" class UnboundColumnRef(_ColOps): """Column reference not yet bound to a specific table.""" __slots__ = ("_name",) def __init__(self, name: str) -> None: self._name = name @property def name(self) -> str: """Column name.""" return self._name def __hash__(self) -> int: return hash(self._name) def __repr__(self) -> str: return f"col({self._name!r})"
[docs] def col(name: str) -> UnboundColumnRef: """Return an unbound column reference for DSL predicates.""" return UnboundColumnRef(name)
__all__ = ["TableRef", "ColumnRef", "UnboundColumnRef", "col"]