Skip to content

Commit a7e4bd0

Browse files
authored
fix: properly validate scd type 2 fields (#1456)
1 parent 9ed0e68 commit a7e4bd0

File tree

2 files changed

+77
-0
lines changed

2 files changed

+77
-0
lines changed

sqlmesh/core/model/kind.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,12 @@ class SCDType2Kind(_ModelKind):
328328
disable_restatement: bool = True
329329

330330
_unique_key_validator = unique_key_validator
331+
_bool_validator = bool_validator
332+
333+
@field_validator("valid_from_name", "valid_to_name", "updated_at_name", mode="before")
334+
@classmethod
335+
def _string_validator(cls, v: t.Any) -> str:
336+
return v.name if isinstance(v, exp.Expression) else str(v)
331337

332338
@property
333339
def managed_columns(self) -> t.Dict[str, exp.DataType]:

tests/core/test_model.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2106,3 +2106,74 @@ def test_interval_unit_validation():
21062106
).interval_unit_
21072107
is None
21082108
)
2109+
2110+
2111+
def test_scd_type_2_defaults():
2112+
view_model_expressions = d.parse(
2113+
"""
2114+
MODEL (
2115+
name db.table,
2116+
kind SCD_TYPE_2 (
2117+
unique_key id,
2118+
),
2119+
);
2120+
SELECT
2121+
1 as id,
2122+
'2020-01-01' as ds,
2123+
'2020-01-01' as test_updated_at,
2124+
'2020-01-01' as test_valid_from,
2125+
'2020-01-01' as test_valid_to
2126+
;
2127+
"""
2128+
)
2129+
scd_type_2_model = load_sql_based_model(view_model_expressions)
2130+
assert scd_type_2_model.unique_key == ["id"]
2131+
assert scd_type_2_model.managed_columns == {
2132+
"valid_from": exp.DataType.build("TIMESTAMP"),
2133+
"valid_to": exp.DataType.build("TIMESTAMP"),
2134+
}
2135+
assert scd_type_2_model.kind.updated_at_name == "updated_at"
2136+
assert scd_type_2_model.kind.valid_from_name == "valid_from"
2137+
assert scd_type_2_model.kind.valid_to_name == "valid_to"
2138+
assert scd_type_2_model.kind.is_scd_type_2
2139+
assert scd_type_2_model.kind.is_materialized
2140+
assert scd_type_2_model.kind.forward_only
2141+
assert scd_type_2_model.kind.disable_restatement
2142+
2143+
2144+
def test_scd_type_2_overrides():
2145+
view_model_expressions = d.parse(
2146+
"""
2147+
MODEL (
2148+
name db.table,
2149+
kind SCD_TYPE_2 (
2150+
unique_key [id, ds],
2151+
updated_at_name test_updated_at,
2152+
valid_from_name test_valid_from,
2153+
valid_to_name test_valid_to,
2154+
forward_only False,
2155+
disable_restatement False,
2156+
),
2157+
);
2158+
SELECT
2159+
1 as id,
2160+
'2020-01-01' as ds,
2161+
'2020-01-01' as test_updated_at,
2162+
'2020-01-01' as test_valid_from,
2163+
'2020-01-01' as test_valid_to
2164+
;
2165+
"""
2166+
)
2167+
scd_type_2_model = load_sql_based_model(view_model_expressions)
2168+
assert scd_type_2_model.unique_key == ["id", "ds"]
2169+
assert scd_type_2_model.managed_columns == {
2170+
"test_valid_from": exp.DataType.build("TIMESTAMP"),
2171+
"test_valid_to": exp.DataType.build("TIMESTAMP"),
2172+
}
2173+
assert scd_type_2_model.kind.updated_at_name == "test_updated_at"
2174+
assert scd_type_2_model.kind.valid_from_name == "test_valid_from"
2175+
assert scd_type_2_model.kind.valid_to_name == "test_valid_to"
2176+
assert scd_type_2_model.kind.is_scd_type_2
2177+
assert scd_type_2_model.kind.is_materialized
2178+
assert not scd_type_2_model.kind.forward_only
2179+
assert not scd_type_2_model.kind.disable_restatement

0 commit comments

Comments
 (0)