From 59286e0eee9a80dd5a7ac2fd1755b8cfb11e4d70 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Mon, 17 Jun 2024 12:31:28 -0700 Subject: [PATCH 1/5] Rename time spine files & classes for simplicity These are based on models (semantic difference from tables). And all YAML specs are configurations, so that piece just seemed redundant. --- .../implementations/project_configuration.py | 6 ++---- ..._spine_table_configuration.py => time_spine.py} | 10 ++++------ .../protocols/project_configuration.py | 6 ++---- .../{time_spine_configuration.py => time_spine.py} | 2 +- tests/example_project_configuration.py | 6 ++---- tests/test_implements_satisfy_protocols.py | 14 +++++--------- 6 files changed, 16 insertions(+), 28 deletions(-) rename dbt_semantic_interfaces/implementations/{time_spine_table_configuration.py => time_spine.py} (60%) rename dbt_semantic_interfaces/protocols/{time_spine_configuration.py => time_spine.py} (95%) diff --git a/dbt_semantic_interfaces/implementations/project_configuration.py b/dbt_semantic_interfaces/implementations/project_configuration.py index 1be46fcf..4617ae02 100644 --- a/dbt_semantic_interfaces/implementations/project_configuration.py +++ b/dbt_semantic_interfaces/implementations/project_configuration.py @@ -14,9 +14,7 @@ UNKNOWN_VERSION_SENTINEL, PydanticSemanticVersion, ) -from dbt_semantic_interfaces.implementations.time_spine_table_configuration import ( - PydanticTimeSpineTableConfiguration, -) +from dbt_semantic_interfaces.implementations.time_spine import PydanticTimeSpine from dbt_semantic_interfaces.protocols import ProtocolHint from dbt_semantic_interfaces.protocols.project_configuration import ProjectConfiguration from dsi_pydantic_shim import validator @@ -29,7 +27,7 @@ class PydanticProjectConfiguration(HashableBaseModel, ModelWithMetadataParsing, def _implements_protocol(self) -> ProjectConfiguration: return self - time_spine_table_configurations: List[PydanticTimeSpineTableConfiguration] + time_spine_table_configurations: List[PydanticTimeSpine] metadata: Optional[PydanticMetadata] = None dsi_package_version: PydanticSemanticVersion = UNKNOWN_VERSION_SENTINEL diff --git a/dbt_semantic_interfaces/implementations/time_spine_table_configuration.py b/dbt_semantic_interfaces/implementations/time_spine.py similarity index 60% rename from dbt_semantic_interfaces/implementations/time_spine_table_configuration.py rename to dbt_semantic_interfaces/implementations/time_spine.py index 9bab71f8..8a8bafee 100644 --- a/dbt_semantic_interfaces/implementations/time_spine_table_configuration.py +++ b/dbt_semantic_interfaces/implementations/time_spine.py @@ -7,19 +7,17 @@ ModelWithMetadataParsing, ) from dbt_semantic_interfaces.protocols import ProtocolHint -from dbt_semantic_interfaces.protocols.time_spine_configuration import ( - TimeSpineTableConfiguration, +from dbt_semantic_interfaces.protocols.time_spine import ( + TimeSpine, ) from dbt_semantic_interfaces.type_enums import TimeGranularity -class PydanticTimeSpineTableConfiguration( - HashableBaseModel, ModelWithMetadataParsing, ProtocolHint[TimeSpineTableConfiguration] -): +class PydanticTimeSpine(HashableBaseModel, ModelWithMetadataParsing, ProtocolHint[TimeSpine]): """Pydantic implementation of SemanticVersion.""" @override - def _implements_protocol(self) -> TimeSpineTableConfiguration: + def _implements_protocol(self) -> TimeSpine: return self location: str diff --git a/dbt_semantic_interfaces/protocols/project_configuration.py b/dbt_semantic_interfaces/protocols/project_configuration.py index e2248bb3..da4746da 100644 --- a/dbt_semantic_interfaces/protocols/project_configuration.py +++ b/dbt_semantic_interfaces/protocols/project_configuration.py @@ -2,9 +2,7 @@ from typing import Protocol, Sequence from dbt_semantic_interfaces.protocols.semantic_version import SemanticVersion -from dbt_semantic_interfaces.protocols.time_spine_configuration import ( - TimeSpineTableConfiguration, -) +from dbt_semantic_interfaces.protocols.time_spine import TimeSpine class ProjectConfiguration(Protocol): @@ -18,6 +16,6 @@ def dsi_package_version(self) -> SemanticVersion: @property @abstractmethod - def time_spine_table_configurations(self) -> Sequence[TimeSpineTableConfiguration]: + def time_spine_table_configurations(self) -> Sequence[TimeSpine]: """The time spine table configurations. Multiple allowed for different time grains.""" pass diff --git a/dbt_semantic_interfaces/protocols/time_spine_configuration.py b/dbt_semantic_interfaces/protocols/time_spine.py similarity index 95% rename from dbt_semantic_interfaces/protocols/time_spine_configuration.py rename to dbt_semantic_interfaces/protocols/time_spine.py index de0579a7..209bd2f5 100644 --- a/dbt_semantic_interfaces/protocols/time_spine_configuration.py +++ b/dbt_semantic_interfaces/protocols/time_spine.py @@ -4,7 +4,7 @@ from dbt_semantic_interfaces.type_enums import TimeGranularity -class TimeSpineTableConfiguration(Protocol): +class TimeSpine(Protocol): """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. diff --git a/tests/example_project_configuration.py b/tests/example_project_configuration.py index b7cd99aa..41f6d4ad 100644 --- a/tests/example_project_configuration.py +++ b/tests/example_project_configuration.py @@ -3,15 +3,13 @@ from dbt_semantic_interfaces.implementations.project_configuration import ( PydanticProjectConfiguration, ) -from dbt_semantic_interfaces.implementations.time_spine_table_configuration import ( - PydanticTimeSpineTableConfiguration, -) +from dbt_semantic_interfaces.implementations.time_spine import PydanticTimeSpine from dbt_semantic_interfaces.parsing.objects import YamlConfigFile from dbt_semantic_interfaces.type_enums import TimeGranularity EXAMPLE_PROJECT_CONFIGURATION = PydanticProjectConfiguration( time_spine_table_configurations=[ - PydanticTimeSpineTableConfiguration( + PydanticTimeSpine( location="example_schema.example_table", column_name="ds", grain=TimeGranularity.DAY, diff --git a/tests/test_implements_satisfy_protocols.py b/tests/test_implements_satisfy_protocols.py index 44b34a3b..f369f82b 100644 --- a/tests/test_implements_satisfy_protocols.py +++ b/tests/test_implements_satisfy_protocols.py @@ -35,9 +35,7 @@ PydanticSemanticManifest, ) from dbt_semantic_interfaces.implementations.semantic_model import PydanticSemanticModel -from dbt_semantic_interfaces.implementations.time_spine_table_configuration import ( - PydanticTimeSpineTableConfiguration, -) +from dbt_semantic_interfaces.implementations.time_spine import PydanticTimeSpine from dbt_semantic_interfaces.protocols import Dimension as DimensionProtocol from dbt_semantic_interfaces.protocols import Entity as EntityProtocol from dbt_semantic_interfaces.protocols import Measure as MeasureProtocol @@ -48,9 +46,7 @@ SemanticManifest as SemanticManifestProtocol, ) from dbt_semantic_interfaces.protocols import SemanticModel as SemanticModelProtocol -from dbt_semantic_interfaces.protocols.time_spine_configuration import ( - TimeSpineTableConfiguration as TimeSpineTableConfigurationProtocol, -) +from dbt_semantic_interfaces.protocols.time_spine import TimeSpine as TimeSpineProtocol from dbt_semantic_interfaces.type_enums import DimensionType, MetricType OPTIONAL_STR_STRATEGY = text() | none() @@ -284,12 +280,12 @@ def test_saved_query_protocol(saved_query: PydanticSavedQuery) -> None: # noqa: @runtime_checkable -class RuntimeCheckableTimeSpineConfiguration(TimeSpineTableConfigurationProtocol, Protocol): +class RuntimeCheckableTimeSpineConfiguration(TimeSpineProtocol, Protocol): """We don't want runtime_checkable versions of protocols in the package, but we want them for tests.""" pass -@given(builds(PydanticTimeSpineTableConfiguration)) -def test_time_spine_table_configuration_protocol(time_spine: PydanticTimeSpineTableConfiguration) -> None: # noqa: D +@given(builds(PydanticTimeSpine)) +def test_time_spine_table_configuration_protocol(time_spine: PydanticTimeSpine) -> None: # noqa: D assert isinstance(time_spine, RuntimeCheckableTimeSpineConfiguration) From 3056ea500760811fe8dff27cc1a89bc592229b4f Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Mon, 17 Jun 2024 12:34:01 -0700 Subject: [PATCH 2/5] Update NodeRelation implementation class to follow patterns used by other implementation classes --- .../implementations/semantic_model.py | 15 ++++++++++----- .../implementations/time_spine.py | 4 +--- dbt_semantic_interfaces/test_utils.py | 6 +++--- tests/validations/test_reserved_keywords.py | 4 ++-- 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/dbt_semantic_interfaces/implementations/semantic_model.py b/dbt_semantic_interfaces/implementations/semantic_model.py index 90b4a89e..f119bdef 100644 --- a/dbt_semantic_interfaces/implementations/semantic_model.py +++ b/dbt_semantic_interfaces/implementations/semantic_model.py @@ -18,6 +18,7 @@ SemanticModelConfig, SemanticModelDefaults, ) +from dbt_semantic_interfaces.protocols.semantic_model import NodeRelation from dbt_semantic_interfaces.references import ( EntityReference, LinkableElementReference, @@ -28,7 +29,7 @@ from dsi_pydantic_shim import Field, validator -class NodeRelation(HashableBaseModel): +class PydanticNodeRelation(HashableBaseModel, ProtocolHint[NodeRelation]): """Path object to where the data should be.""" alias: str @@ -36,6 +37,10 @@ class NodeRelation(HashableBaseModel): database: Optional[str] = None relation_name: str = "" + @override + def _implements_protocol(self) -> NodeRelation: # noqa: D + return self + @validator("relation_name", always=True) @classmethod def __create_default_relation_name(cls, value: Any, values: Any) -> str: # type: ignore[misc] @@ -57,12 +62,12 @@ def __create_default_relation_name(cls, value: Any, values: Any) -> str: # type return value @staticmethod - def from_string(sql_str: str) -> NodeRelation: # noqa: D + def from_string(sql_str: str) -> PydanticNodeRelation: # noqa: D sql_str_split = sql_str.split(".") if len(sql_str_split) == 2: - return NodeRelation(schema_name=sql_str_split[0], alias=sql_str_split[1]) + return PydanticNodeRelation(schema_name=sql_str_split[0], alias=sql_str_split[1]) elif len(sql_str_split) == 3: - return NodeRelation(database=sql_str_split[0], schema_name=sql_str_split[1], alias=sql_str_split[2]) + return PydanticNodeRelation(database=sql_str_split[0], schema_name=sql_str_split[1], alias=sql_str_split[2]) raise RuntimeError( f"Invalid input for a SQL table, expected form '.' or '..
' " f"but got: {sql_str}" @@ -95,7 +100,7 @@ def _implements_protocol(self) -> SemanticModel: name: str defaults: Optional[PydanticSemanticModelDefaults] description: Optional[str] - node_relation: NodeRelation + node_relation: PydanticNodeRelation primary_entity: Optional[str] entities: Sequence[PydanticEntity] = [] diff --git a/dbt_semantic_interfaces/implementations/time_spine.py b/dbt_semantic_interfaces/implementations/time_spine.py index 8a8bafee..02a787a2 100644 --- a/dbt_semantic_interfaces/implementations/time_spine.py +++ b/dbt_semantic_interfaces/implementations/time_spine.py @@ -7,9 +7,7 @@ ModelWithMetadataParsing, ) from dbt_semantic_interfaces.protocols import ProtocolHint -from dbt_semantic_interfaces.protocols.time_spine import ( - TimeSpine, -) +from dbt_semantic_interfaces.protocols.time_spine import TimeSpine from dbt_semantic_interfaces.type_enums import TimeGranularity diff --git a/dbt_semantic_interfaces/test_utils.py b/dbt_semantic_interfaces/test_utils.py index addd1b93..0b2fefbe 100644 --- a/dbt_semantic_interfaces/test_utils.py +++ b/dbt_semantic_interfaces/test_utils.py @@ -20,7 +20,7 @@ PydanticSemanticManifest, ) from dbt_semantic_interfaces.implementations.semantic_model import ( - NodeRelation, + PydanticNodeRelation, PydanticSemanticModel, ) from dbt_semantic_interfaces.parsing.objects import YamlConfigFile @@ -141,7 +141,7 @@ def metric_with_guaranteed_meta( def semantic_model_with_guaranteed_meta( name: str, description: Optional[str] = None, - node_relation: Optional[NodeRelation] = None, + node_relation: Optional[PydanticNodeRelation] = None, metadata: PydanticMetadata = default_meta(), entities: Sequence[PydanticEntity] = (), measures: Sequence[PydanticMeasure] = (), @@ -153,7 +153,7 @@ def semantic_model_with_guaranteed_meta( """ created_node_relation = node_relation if created_node_relation is None: - created_node_relation = NodeRelation( + created_node_relation = PydanticNodeRelation( schema_name="schema", alias="table", ) diff --git a/tests/validations/test_reserved_keywords.py b/tests/validations/test_reserved_keywords.py index e1d477d5..85cd8b02 100644 --- a/tests/validations/test_reserved_keywords.py +++ b/tests/validations/test_reserved_keywords.py @@ -4,7 +4,7 @@ from dbt_semantic_interfaces.implementations.semantic_manifest import ( PydanticSemanticManifest, ) -from dbt_semantic_interfaces.implementations.semantic_model import NodeRelation +from dbt_semantic_interfaces.implementations.semantic_model import PydanticNodeRelation from dbt_semantic_interfaces.test_utils import find_semantic_model_with from dbt_semantic_interfaces.validations.reserved_keywords import ( RESERVED_KEYWORDS, @@ -76,7 +76,7 @@ def test_reserved_keywords_in_node_relation( # noqa: D (semantic_model_with_node_relation, _index) = find_semantic_model_with( model=model, function=lambda semantic_model: semantic_model.node_relation is not None ) - semantic_model_with_node_relation.node_relation = NodeRelation( + semantic_model_with_node_relation.node_relation = PydanticNodeRelation( alias=random_keyword(), schema_name="some_schema", ) From 9c993ad1d9b76a3c9c00dab1a62ddc9928106d22 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Mon, 17 Jun 2024 12:40:07 -0700 Subject: [PATCH 3/5] Implement new time spine YAML keys As we work to support sub-daily granularities, users will be able to set up multiple time spines at different granularities. Currently, these time spines are not configured in YAML, and these fields are set in core instead and show up in the manifest. That means we should be able to change the names here as long as we also update them in core and anywhere they are handled downstream, such as MF or MFS. --- .../implementations/project_configuration.py | 2 +- .../implementations/time_spine.py | 10 ++++--- .../default_explicit_schema.json | 28 +++++++++---------- dbt_semantic_interfaces/parsing/schemas.py | 21 +++++++------- .../protocols/project_configuration.py | 2 +- .../protocols/time_spine.py | 27 ++++++++++++------ tests/example_project_configuration.py | 21 ++++++++------ .../project_configuration.yaml | 11 +++++--- 8 files changed, 70 insertions(+), 52 deletions(-) diff --git a/dbt_semantic_interfaces/implementations/project_configuration.py b/dbt_semantic_interfaces/implementations/project_configuration.py index 4617ae02..63cbf3f6 100644 --- a/dbt_semantic_interfaces/implementations/project_configuration.py +++ b/dbt_semantic_interfaces/implementations/project_configuration.py @@ -27,7 +27,7 @@ class PydanticProjectConfiguration(HashableBaseModel, ModelWithMetadataParsing, def _implements_protocol(self) -> ProjectConfiguration: return self - time_spine_table_configurations: List[PydanticTimeSpine] + time_spines: List[PydanticTimeSpine] metadata: Optional[PydanticMetadata] = None dsi_package_version: PydanticSemanticVersion = UNKNOWN_VERSION_SENTINEL diff --git a/dbt_semantic_interfaces/implementations/time_spine.py b/dbt_semantic_interfaces/implementations/time_spine.py index 02a787a2..7ed08ea8 100644 --- a/dbt_semantic_interfaces/implementations/time_spine.py +++ b/dbt_semantic_interfaces/implementations/time_spine.py @@ -6,18 +6,20 @@ HashableBaseModel, ModelWithMetadataParsing, ) +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 from dbt_semantic_interfaces.type_enums import TimeGranularity class PydanticTimeSpine(HashableBaseModel, ModelWithMetadataParsing, ProtocolHint[TimeSpine]): - """Pydantic implementation of SemanticVersion.""" + """Pydantic implementation of TimeSpine.""" @override def _implements_protocol(self) -> TimeSpine: return self - location: str - column_name: str - grain: TimeGranularity + name: str + node_relation: PydanticNodeRelation + base_column: str + base_granularity: TimeGranularity diff --git a/dbt_semantic_interfaces/parsing/generated_json_schemas/default_explicit_schema.json b/dbt_semantic_interfaces/parsing/generated_json_schemas/default_explicit_schema.json index 38047288..fec054bd 100644 --- a/dbt_semantic_interfaces/parsing/generated_json_schemas/default_explicit_schema.json +++ b/dbt_semantic_interfaces/parsing/generated_json_schemas/default_explicit_schema.json @@ -540,15 +540,15 @@ "$id": "project_configuration_schema", "additionalProperties": false, "properties": { - "time_spine_table_configurations": { + "time_spines": { "items": { - "$ref": "#/definitions/time_spine_table_configuration_schema" + "$ref": "#/definitions/time_spine_schema" }, "type": "array" } }, "required": [ - "time_spine_table_configurations" + "time_spines" ], "type": "object" }, @@ -680,14 +680,14 @@ ], "type": "object" }, - "time_spine_table_configuration_schema": { - "$id": "time_spine_table_configuration_schema", + "time_spine_schema": { + "$id": "time_spine_schema", "additionalProperties": false, "properties": { - "column_name": { - "type": "string" - }, - "grain": { + "name": {"type": "string"}, + "node_relation": {"$ref": "node_relation_schema"}, + "base_column": {"type": "string"}, + "base_granularity": { "enum": [ "NANOSECOND", "MICROSECOND", @@ -712,15 +712,13 @@ "quarter", "year" ] - }, - "location": { - "type": "string" } }, "required": [ - "location", - "column_name", - "grain" + "name", + "node_relation", + "base_column", + "base_granularity" ], "type": "object" }, diff --git a/dbt_semantic_interfaces/parsing/schemas.py b/dbt_semantic_interfaces/parsing/schemas.py index 78a60f3e..f561ce7f 100644 --- a/dbt_semantic_interfaces/parsing/schemas.py +++ b/dbt_semantic_interfaces/parsing/schemas.py @@ -318,16 +318,17 @@ } -time_spine_table_configuration_schema = { - "$id": "time_spine_table_configuration_schema", +time_spine_schema = { + "$id": "time_spine_schema", "type": "object", "properties": { - "location": {"type": "string"}, - "column_name": {"type": "string"}, - "grain": {"enum": time_granularity_values}, + "name": {"type": "string"}, + "node_relation": {"$ref": "node_relation_schema"}, + "base_column": {"type": "string"}, + "base_granularity": {"enum": time_granularity_values}, }, "additionalProperties": False, - "required": ["location", "column_name", "grain"], + "required": ["name", "node_relation", "base_column", "base_granularity"], } @@ -335,13 +336,13 @@ "$id": "project_configuration_schema", "type": "object", "properties": { - "time_spine_table_configurations": { + "time_spines": { "type": "array", - "items": {"$ref": "time_spine_table_configuration_schema"}, + "items": {"$ref": "time_spine_schema"}, }, }, "additionalProperties": False, - "required": ["time_spine_table_configurations"], + "required": ["time_spines"], } export_config_schema = { @@ -456,7 +457,7 @@ metric_input_schema["$id"]: metric_input_schema, 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, export_schema["$id"]: export_schema, export_config_schema["$id"]: export_config_schema, saved_query_query_params_schema["$id"]: saved_query_query_params_schema, diff --git a/dbt_semantic_interfaces/protocols/project_configuration.py b/dbt_semantic_interfaces/protocols/project_configuration.py index da4746da..737bc96b 100644 --- a/dbt_semantic_interfaces/protocols/project_configuration.py +++ b/dbt_semantic_interfaces/protocols/project_configuration.py @@ -16,6 +16,6 @@ def dsi_package_version(self) -> SemanticVersion: @property @abstractmethod - def time_spine_table_configurations(self) -> Sequence[TimeSpine]: + def time_spines(self) -> Sequence[TimeSpine]: """The time spine table configurations. Multiple allowed for different time grains.""" pass diff --git a/dbt_semantic_interfaces/protocols/time_spine.py b/dbt_semantic_interfaces/protocols/time_spine.py index 209bd2f5..8381d187 100644 --- a/dbt_semantic_interfaces/protocols/time_spine.py +++ b/dbt_semantic_interfaces/protocols/time_spine.py @@ -1,13 +1,14 @@ from abc import abstractmethod from typing import Protocol +from dbt_semantic_interfaces.protocols.semantic_model import NodeRelation from dbt_semantic_interfaces.type_enums import TimeGranularity class TimeSpine(Protocol): """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. + A time spine table is a table with at least one column containing dates at a specific grain. e.g. with day granularity: ... @@ -15,23 +16,31 @@ class TimeSpine(Protocol): 2020-01-02 2020-01-03 ... - - The time spine table is used to join to the measure source to compute cumulative metrics. """ @property @abstractmethod - def location(self) -> str: - """The location of the time spine table in schema_name.table_name format.""" + def name(self) -> str: + """Name used to reference this time spine.""" pass @property @abstractmethod - def column_name(self) -> str: - """The name of the column in the time spine table that has the date values.""" + def node_relation(self) -> NodeRelation: + """dbt model that represents the time spine.""" # noqa: D403 + pass @property @abstractmethod - def grain(self) -> TimeGranularity: - """The grain of the dates in the time spine table.""" + def base_column(self) -> str: + """The name of the column in the time spine table that has the values at the base granularity.""" + pass + + @property + @abstractmethod + def base_granularity(self) -> TimeGranularity: + """The grain of the dates in the base_column. + + Must map to one of the default TimeGranularity values, not a custom granularity. + """ pass diff --git a/tests/example_project_configuration.py b/tests/example_project_configuration.py index 41f6d4ad..29ca1c89 100644 --- a/tests/example_project_configuration.py +++ b/tests/example_project_configuration.py @@ -3,16 +3,18 @@ from dbt_semantic_interfaces.implementations.project_configuration import ( PydanticProjectConfiguration, ) +from dbt_semantic_interfaces.implementations.semantic_model import PydanticNodeRelation from dbt_semantic_interfaces.implementations.time_spine import PydanticTimeSpine from dbt_semantic_interfaces.parsing.objects import YamlConfigFile from dbt_semantic_interfaces.type_enums import TimeGranularity EXAMPLE_PROJECT_CONFIGURATION = PydanticProjectConfiguration( - time_spine_table_configurations=[ + time_spines=[ PydanticTimeSpine( - location="example_schema.example_table", - column_name="ds", - grain=TimeGranularity.DAY, + name="example_time_spine", + node_relation=PydanticNodeRelation(schema_name="example_schema", alias="example_table"), + base_column="ds", + base_granularity=TimeGranularity.DAY, ) ], ) @@ -22,10 +24,13 @@ contents=textwrap.dedent( """\ project_configuration: - time_spine_table_configurations: - - location: example_schema.example_table - column_name: ds - grain: day + time_spines: + - name: sample + node_relation: + schema_name: sample + alias: sample + base_column: ds + base_granularity: day """ ), ) diff --git a/tests/fixtures/semantic_manifest_yamls/simple_semantic_manifest/project_configuration.yaml b/tests/fixtures/semantic_manifest_yamls/simple_semantic_manifest/project_configuration.yaml index 7840fe9f..601a5733 100644 --- a/tests/fixtures/semantic_manifest_yamls/simple_semantic_manifest/project_configuration.yaml +++ b/tests/fixtures/semantic_manifest_yamls/simple_semantic_manifest/project_configuration.yaml @@ -1,6 +1,9 @@ --- project_configuration: - time_spine_table_configurations: - - location: example_schema.example_table - column_name: ds - grain: day + time_spines: + - name: time_spine_day + node_relation: + alias: example_table + schema_name: example_schema + base_column: ds + base_granularity: day From fdbe40e93d8d932399a4817fd750e56968f55f06 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Mon, 17 Jun 2024 12:40:45 -0700 Subject: [PATCH 4/5] Reformat JSON schema --- .../default_explicit_schema.json | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/dbt_semantic_interfaces/parsing/generated_json_schemas/default_explicit_schema.json b/dbt_semantic_interfaces/parsing/generated_json_schemas/default_explicit_schema.json index fec054bd..0c81b22f 100644 --- a/dbt_semantic_interfaces/parsing/generated_json_schemas/default_explicit_schema.json +++ b/dbt_semantic_interfaces/parsing/generated_json_schemas/default_explicit_schema.json @@ -684,9 +684,9 @@ "$id": "time_spine_schema", "additionalProperties": false, "properties": { - "name": {"type": "string"}, - "node_relation": {"$ref": "node_relation_schema"}, - "base_column": {"type": "string"}, + "base_column": { + "type": "string" + }, "base_granularity": { "enum": [ "NANOSECOND", @@ -712,6 +712,12 @@ "quarter", "year" ] + }, + "name": { + "type": "string" + }, + "node_relation": { + "$ref": "#/definitions/node_relation_schema" } }, "required": [ From 9312f66558cd3cedc6e491c600a39116ec311d08 Mon Sep 17 00:00:00 2001 From: Courtney Holcomb Date: Mon, 17 Jun 2024 12:47:25 -0700 Subject: [PATCH 5/5] Changelog --- .changes/unreleased/Features-20240617-124717.yaml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changes/unreleased/Features-20240617-124717.yaml diff --git a/.changes/unreleased/Features-20240617-124717.yaml b/.changes/unreleased/Features-20240617-124717.yaml new file mode 100644 index 00000000..d553c68b --- /dev/null +++ b/.changes/unreleased/Features-20240617-124717.yaml @@ -0,0 +1,6 @@ +kind: Features +body: Support for configuring multiple time spines at different granularities. +time: 2024-06-17T12:47:17.06019-07:00 +custom: + Author: courtneyholcomb + Issue: "280"