Skip to content

Commit 70dd9d2

Browse files
authored
fix: fix time_data_type serialization/deserialization (#2342)
* fix: fix time_data_type serialization/deserialization * bump sqlglot
1 parent bbe44a3 commit 70dd9d2

File tree

3 files changed

+41
-4
lines changed

3 files changed

+41
-4
lines changed

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
"requests",
4646
"rich[jupyter]",
4747
"ruamel.yaml",
48-
"sqlglot[rs]~=23.0.3",
48+
"sqlglot[rs]~=23.2.0",
4949
],
5050
extras_require={
5151
"bigquery": [

sqlmesh/core/model/kind.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -370,20 +370,23 @@ class _SCDType2Kind(_ModelKind):
370370
valid_from_name: SQLGlotString = "valid_from"
371371
valid_to_name: SQLGlotString = "valid_to"
372372
invalidate_hard_deletes: SQLGlotBool = False
373-
time_data_type: exp.DataType = exp.DataType.build("TIMESTAMP")
373+
time_data_type: exp.DataType = Field(exp.DataType.build("TIMESTAMP"), validate_default=True)
374374

375375
forward_only: SQLGlotBool = True
376376
disable_restatement: SQLGlotBool = True
377377

378-
@field_validator("time_data_type", mode="before")
378+
# always=True can be removed once Pydantic 1 is deprecated
379+
@field_validator("time_data_type", mode="before", always=True)
379380
@classmethod
380381
def _time_data_type_validator(
381382
cls, v: t.Union[str, exp.Expression], values: t.Any
382383
) -> exp.Expression:
383384
values = values if isinstance(values, dict) else values.data
384385
if isinstance(v, exp.Expression) and not isinstance(v, exp.DataType):
385386
v = v.name
386-
return exp.DataType.build(v, dialect=values.get("dialect"))
387+
data_type = exp.DataType.build(v, dialect=values.get("dialect"))
388+
data_type.meta["dialect"] = values.get("dialect")
389+
return data_type
387390

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

tests/core/test_model.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,40 @@ def test_json_serde():
444444
assert deserialized_model == model
445445

446446

447+
def test_scd_type_2_by_col_serde():
448+
expressions = parse(
449+
"""
450+
MODEL(
451+
name test_model,
452+
KIND SCD_TYPE_2_BY_COLUMN (
453+
unique_key a,
454+
columns *,
455+
),
456+
cron '@daily',
457+
owner 'reakman',
458+
grain a,
459+
dialect bigquery
460+
);
461+
462+
SELECT a, ds FROM `tbl`
463+
""",
464+
default_dialect="bigquery",
465+
)
466+
467+
model = load_sql_based_model(expressions)
468+
469+
model_json = model.json()
470+
model_json_parsed = json.loads(model.json())
471+
assert model_json_parsed["kind"]["dialect"] == "bigquery"
472+
assert model_json_parsed["kind"]["unique_key"] == ["`a`"]
473+
assert model_json_parsed["kind"]["columns"] == "*"
474+
# Bigquery converts TIMESTAMP -> DATETIME
475+
assert model_json_parsed["kind"]["time_data_type"] == "DATETIME"
476+
477+
deserialized_model = SqlModel.parse_raw(model_json)
478+
assert deserialized_model.dict() == model.dict()
479+
480+
447481
def test_column_descriptions(sushi_context, assert_exp_eq):
448482
assert sushi_context.models[
449483
'"memory"."sushi"."customer_revenue_by_day"'

0 commit comments

Comments
 (0)