Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions sqlmesh/core/model/definition.py
Original file line number Diff line number Diff line change
Expand Up @@ -2810,6 +2810,13 @@ def render_field_value(value: t.Any) -> t.Any:
for key, value in field_value.items():
if key in RUNTIME_RENDERED_MODEL_FIELDS:
rendered_dict[key] = parse_strings_with_macro_refs(value, dialect)
elif (
# don't parse kind auto_restatement_cron="@..." kwargs (e.g. @daily) into MacroVar
key == "auto_restatement_cron"
and isinstance(value, str)
and value.lower() in CRON_SHORTCUTS
):
rendered_dict[key] = value
elif (rendered := render_field_value(value)) is not None:
rendered_dict[key] = rendered

Expand Down
34 changes: 32 additions & 2 deletions tests/core/test_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -2882,7 +2882,15 @@ def my_model_2(context):
# no warning with valid kind dict
with patch.object(get_console(), "log_warning") as mock_logger:

@model("kind_valid_dict", kind=dict(name=ModelKindName.FULL), columns={'"COL"': "int"})
@model(
"kind_valid_dict",
kind=dict(
name=ModelKindName.INCREMENTAL_BY_TIME_RANGE,
time_column="ds",
auto_restatement_cron="@hourly",
),
columns={'"ds"': "date", '"COL"': "int"},
)
def my_model(context):
pass

Expand All @@ -2891,11 +2899,33 @@ def my_model(context):
path=Path("."),
)

assert isinstance(python_model.kind, FullKind)
assert isinstance(python_model.kind, IncrementalByTimeRangeKind)

assert not mock_logger.call_args


def test_python_model_decorator_auto_restatement_cron() -> None:
@model(
"auto_restatement_model",
cron="@daily",
kind=dict(
name=ModelKindName.INCREMENTAL_BY_TIME_RANGE,
time_column="ds",
auto_restatement_cron="@hourly",
),
columns={'"ds"': "date", '"COL"': "int"},
)
def my_model(context):
pass

python_model = model.get_registry()["auto_restatement_model"].model(
module_path=Path("."),
path=Path("."),
)

assert python_model.auto_restatement_cron == "@hourly"


def test_python_model_decorator_col_descriptions() -> None:
# `columns` and `column_descriptions` column names are different cases, but name normalization makes both lower
@model("col_descriptions", columns={"col": "int"}, column_descriptions={"COL": "a column"})
Expand Down