from __future__ import annotations from dataclasses import dataclass, field from typing import Any @dataclass(frozen=True) class Column: name: str data_type: str column_type: str nullable: bool ordinal_position: int @dataclass(frozen=True) class Table: database: str name: str rows_estimate: int | None columns: list[Column] primary_key: list[str] watermark_candidates: list[str] = field(default_factory=list) classifications: list[str] = field(default_factory=list) @property def watermark_columns(self) -> list[str]: by_lower = {column.name.lower(): column.name for column in self.columns} return [by_lower[name.lower()] for name in self.watermark_candidates if name.lower() in by_lower] def table_to_manifest(table: Table, classifications: list[str] | None = None) -> dict[str, Any]: return { "source_database": table.database, "table_name": table.name, "row_estimate": table.rows_estimate, "primary_key": table.primary_key, "watermark_columns": table.watermark_columns, "classifications": classifications if classifications is not None else table.classifications, "columns": [ { "name": column.name, "data_type": column.data_type, "column_type": column.column_type, "nullable": column.nullable, "ordinal_position": column.ordinal_position, } for column in table.columns ], }