Skip to content

Commit

Permalink
Add new time spine config classes
Browse files Browse the repository at this point in the history
  • Loading branch information
courtneyholcomb committed Jul 16, 2024
1 parent b0275a8 commit 4e2ee9e
Show file tree
Hide file tree
Showing 9 changed files with 163 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
UNKNOWN_VERSION_SENTINEL,
PydanticSemanticVersion,
)
from dbt_semantic_interfaces.implementations.time_spine_table_configuration import (
from dbt_semantic_interfaces.implementations.time_spine import PydanticTimeSpine
from dbt_semantic_interfaces.implementations.time_spine_deprecated import (
PydanticTimeSpineTableConfiguration,
)
from dbt_semantic_interfaces.protocols import ProtocolHint
Expand All @@ -32,6 +33,7 @@ def _implements_protocol(self) -> ProjectConfiguration:
time_spine_table_configurations: List[PydanticTimeSpineTableConfiguration]
metadata: Optional[PydanticMetadata] = None
dsi_package_version: PydanticSemanticVersion = UNKNOWN_VERSION_SENTINEL
time_spines: List[PydanticTimeSpine] = []

@validator("dsi_package_version", always=True)
@classmethod
Expand Down
35 changes: 35 additions & 0 deletions dbt_semantic_interfaces/implementations/time_spine.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from __future__ import annotations

from typing_extensions import override

from dbt_semantic_interfaces.implementations.base import HashableBaseModel
from dbt_semantic_interfaces.implementations.semantic_model import PydanticNodeRelation
from dbt_semantic_interfaces.protocols import ProtocolHint
from dbt_semantic_interfaces.protocols.time_spine import (
TimeSpine,
TimeSpinePrimaryColumn,
)
from dbt_semantic_interfaces.type_enums import TimeGranularity


class PydanticTimeSpinePrimaryColumn(HashableBaseModel, ProtocolHint[TimeSpinePrimaryColumn]):
"""Legacy Pydantic implementation of SemanticVersion. In the process of deprecation."""

@override
def _implements_protocol(self) -> TimeSpinePrimaryColumn:
return self

name: str
time_granularity: TimeGranularity


class PydanticTimeSpine(HashableBaseModel, ProtocolHint[TimeSpine]):
"""Legacy Pydantic implementation of SemanticVersion. In the process of deprecation."""

@override
def _implements_protocol(self) -> TimeSpine:
return self

name: str
node_relation: PydanticNodeRelation
primary_column: PydanticTimeSpinePrimaryColumn
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
ModelWithMetadataParsing,
)
from dbt_semantic_interfaces.protocols import ProtocolHint
from dbt_semantic_interfaces.protocols.time_spine_configuration import (
from dbt_semantic_interfaces.protocols.time_spine_deprecated import (
TimeSpineTableConfiguration,
)
from dbt_semantic_interfaces.type_enums import TimeGranularity
Expand All @@ -16,7 +16,7 @@
class PydanticTimeSpineTableConfiguration(
HashableBaseModel, ModelWithMetadataParsing, ProtocolHint[TimeSpineTableConfiguration]
):
"""Pydantic implementation of SemanticVersion."""
"""Legacy Pydantic implementation of SemanticVersion. In the process of deprecation."""

@override
def _implements_protocol(self) -> TimeSpineTableConfiguration:
Expand Down
31 changes: 30 additions & 1 deletion dbt_semantic_interfaces/parsing/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,29 @@
"required": ["location", "column_name", "grain"],
}

time_spine_primary_column_schema = {
"$id": "time_spine_primary_column_schema",
"type": "object",
"properties": {
"name": {"type": "string"},
"time_granularity": {"enum": time_granularity_values},
},
"additionalProperties": False,
"required": ["name", "time_granularity"],
}

time_spine_schema = {
"$id": "time_spine_schema",
"type": "object",
"properties": {
"name": {"type": "string"},
"node_relation": {"$ref": "node_relation_schema"},
"primary_column": {"$ref": "time_spine_primary_column_schema"},
},
"additionalProperties": False,
"required": ["name", "node_relation", "primary_column"],
}


project_configuration_schema = {
"$id": "project_configuration_schema",
Expand All @@ -356,9 +379,13 @@
"type": "array",
"items": {"$ref": "time_spine_table_configuration_schema"},
},
"time_spines": {
"type": "array",
"items": {"$ref": "time_spine_schema"},
},
},
"additionalProperties": False,
"required": ["time_spine_table_configurations"],
"required": [],
}

export_config_schema = {
Expand Down Expand Up @@ -475,6 +502,8 @@
node_relation_schema["$id"]: node_relation_schema,
semantic_model_defaults_schema["$id"]: semantic_model_defaults_schema,
time_spine_table_configuration_schema["$id"]: time_spine_table_configuration_schema,
time_spine_schema["$id"]: time_spine_schema,
time_spine_primary_column_schema["$id"]: time_spine_primary_column_schema,
export_schema["$id"]: export_schema,
export_config_schema["$id"]: export_config_schema,
saved_query_query_params_schema["$id"]: saved_query_query_params_schema,
Expand Down
13 changes: 11 additions & 2 deletions dbt_semantic_interfaces/protocols/project_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@
from typing import Protocol, Sequence

from dbt_semantic_interfaces.protocols.semantic_version import SemanticVersion
from dbt_semantic_interfaces.protocols.time_spine_configuration import (
from dbt_semantic_interfaces.protocols.time_spine import TimeSpine
from dbt_semantic_interfaces.protocols.time_spine_deprecated import (
TimeSpineTableConfiguration,
)

# Check core to make sure this structure is ok


class ProjectConfiguration(Protocol):
"""Configuration options for the project associated with a semantic manifest."""
Expand All @@ -18,6 +21,12 @@ def dsi_package_version(self) -> SemanticVersion:

@property
@abstractmethod
def time_spine_table_configurations(self) -> Sequence[TimeSpineTableConfiguration]:
def time_spines(self) -> Sequence[TimeSpine]:
"""The time spine table configurations. Multiple allowed for different time grains."""
pass

@property
@abstractmethod
def time_spine_table_configurations(self) -> Sequence[TimeSpineTableConfiguration]:
"""Legacy time spine table configurations. In the process of deprecation."""
pass
49 changes: 49 additions & 0 deletions dbt_semantic_interfaces/protocols/time_spine.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
from __future__ import annotations

from abc import abstractmethod
from typing import Protocol

from dbt_semantic_interfaces.implementations.node_relation import NodeRelation
from dbt_semantic_interfaces.type_enums import TimeGranularity


class TimeSpine(Protocol):
"""Describes a table that contains dates at a specific time grain.
One column must map to a standard granularity (one of the TimeGranularity enum members). Others might represent
custom granularity columns. Custom granularity columns are not yet implemented.
"""

@property
@abstractmethod
def name(self) -> str:
"""A name the user assigns to this time spine."""
pass

@property
@abstractmethod
def node_relation(self) -> NodeRelation:
"""dbt model where this time spine lives.""" # noqa: D403
pass

@property
@abstractmethod
def primary_column(self) -> TimeSpinePrimaryColumn:
"""The column in the time spine that maps to one of our standard granularities."""
pass


class TimeSpinePrimaryColumn(Protocol):
"""The column in the time spine that maps to one of our standard granularities."""

@property
@abstractmethod
def name(self) -> str:
"""The column name."""
pass

@property
@abstractmethod
def time_granularity(self) -> TimeGranularity:
"""The column name."""
pass
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
from __future__ import annotations

from abc import abstractmethod
from typing import Protocol

from dbt_semantic_interfaces.type_enums import TimeGranularity


class TimeSpineTableConfiguration(Protocol):
"""Describes the configuration for a time spine table.
"""Legacy time spine class that will eventually be deprecated in favor of TimeSpine.
Describes the configuration for a time spine table.
A time spine table is a table with a single column containing dates at a specific grain.
e.g. with day granularity:
...
2020-01-01
Expand Down
22 changes: 21 additions & 1 deletion tests/example_project_configuration.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import textwrap

from dbt_semantic_interfaces.implementations.node_relation import PydanticNodeRelation
from dbt_semantic_interfaces.implementations.project_configuration import (
PydanticProjectConfiguration,
)
from dbt_semantic_interfaces.implementations.time_spine_table_configuration import (
from dbt_semantic_interfaces.implementations.time_spine import (
PydanticTimeSpine,
PydanticTimeSpinePrimaryColumn,
)
from dbt_semantic_interfaces.implementations.time_spine_deprecated import (
PydanticTimeSpineTableConfiguration,
)
from dbt_semantic_interfaces.parsing.objects import YamlConfigFile
Expand All @@ -17,6 +22,13 @@
grain=TimeGranularity.DAY,
)
],
time_spines=[
PydanticTimeSpine(
name="day_time_spine",
node_relation=PydanticNodeRelation(alias="day_time_spine", schema_name="stuff"),
primary_column=PydanticTimeSpinePrimaryColumn(name="ds_day", time_granularity=TimeGranularity.DAY),
)
],
)

EXAMPLE_PROJECT_CONFIGURATION_YAML_CONFIG_FILE = YamlConfigFile(
Expand All @@ -28,6 +40,14 @@
- location: example_schema.example_table
column_name: ds
grain: day
time_spines:
- name: day_time_spine
node_relation:
schema_name: stuff
alias: day_time_spine
primary_column:
name: ds_day
time_granularity: day
"""
),
)
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,11 @@ project_configuration:
- location: example_schema.example_table
column_name: ds
grain: day
time_spines:
- name: day_time_spine
node_relation:
schema_name: stuff
alias: day_time_spine
primary_column:
name: ds_day
time_granularity: day

0 comments on commit 4e2ee9e

Please sign in to comment.