Source code for codegen_database.plugins.view

"""Generic view plugin for dimension factories."""

from __future__ import annotations

from typing import TYPE_CHECKING

from sqlalchemy import Column, MetaData, Table
from sqlalchemy_declarative_extensions import View, register_view

from codegen_database.plugin import Dynamic, Plugin, produces

if TYPE_CHECKING:
    from collections.abc import Callable

    from codegen_database.factory.context import FactoryContext


[docs] @produces(Dynamic("primary_key"), "__root__") class ViewPlugin(Plugin): """Register a view and store a proxy table in ctx. A generic, composable view plugin. Each factory type provides a ``query_builder`` that returns the view SQL and a ``proxy_builder`` that returns proxy columns for downstream plugins. Args: query_builder: Callable ``(ctx) -> str`` returning the compiled SQL for the view definition. proxy_builder: Callable ``(ctx) -> list[Column]`` returning proxy columns for the view's selectable proxy. primary_key: Key in ``ctx`` to store the view proxy under (default ``"primary"``). extra_requires: Additional ctx keys this plugin depends on. Declared to the topological sorter so that upstream plugins run first. """ def __init__( self, query_builder: Callable[[FactoryContext], str], proxy_builder: Callable[[FactoryContext], list[Column]], primary_key: str = "primary", extra_requires: list[str] | None = None, ) -> None: """Store configuration.""" self.query_builder = query_builder self.proxy_builder = proxy_builder self.primary_key = primary_key self._extra_requires = extra_requires or []
[docs] def resolved_requires(self) -> list[str]: """Return base requires plus extra runtime keys.""" base = super().resolved_requires() return base + list(self._extra_requires)
[docs] def run(self, ctx: FactoryContext) -> None: """Register the view and store the proxy in ctx.""" sql = self.query_builder(ctx) register_view( ctx.metadata, View( ctx.tablename, sql, schema=ctx.schemaname, ), ) proxy = Table( ctx.tablename, MetaData(), *self.proxy_builder(ctx), schema=ctx.schemaname, ) ctx[self.primary_key] = proxy ctx["__root__"] = proxy