From 65bf3def568a4ca75fb5b7e624ee8bdb2a0056da Mon Sep 17 00:00:00 2001 From: Iaroslav Zeigerman Date: Thu, 9 Jan 2025 12:58:13 -0800 Subject: [PATCH] Fix: The interval unit can be larger than cron perid of allow_partials is set to true --- sqlmesh/core/node.py | 4 ++-- tests/core/test_model.py | 35 +++++++++++++++++++++++++++++++++-- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/sqlmesh/core/node.py b/sqlmesh/core/node.py index e86102a5f4..6f2ff85b0e 100644 --- a/sqlmesh/core/node.py +++ b/sqlmesh/core/node.py @@ -260,12 +260,12 @@ def _interval_unit_validator(cls, v: t.Any) -> t.Optional[t.Union[IntervalUnit, @model_validator_v1_args def _node_root_validator(cls, values: t.Dict[str, t.Any]) -> t.Dict[str, t.Any]: interval_unit = values.get("interval_unit_") - if interval_unit: + if interval_unit and not values.get("allow_partials"): cron = values["cron"] max_interval_unit = IntervalUnit.from_cron(cron) if interval_unit.seconds > max_interval_unit.seconds: raise ConfigError( - f"Interval unit of '{interval_unit}' is larger than cron period of '{cron}'" + f"Cron '{cron}' cannot be more frequent than interval unit '{interval_unit.value}'. If this is intentional, set allow_partials to True." ) start = values.get("start") end = values.get("end") diff --git a/tests/core/test_model.py b/tests/core/test_model.py index 68d91c1a8e..087647cc17 100644 --- a/tests/core/test_model.py +++ b/tests/core/test_model.py @@ -2908,20 +2908,51 @@ def test_custom_interval_unit(): ) with pytest.raises( - ConfigError, match=r"Interval unit of '.*' is larger than cron period of '@daily'" + ConfigError, match=r"Cron '@daily' cannot be more frequent than interval unit 'month'." ): load_sql_based_model( d.parse("MODEL (name db.table, interval_unit month); SELECT a FROM tbl;") ) with pytest.raises( - ConfigError, match=r"Interval unit of '.*' is larger than cron period of '@hourly'" + ConfigError, + match=r"Cron '@hourly' cannot be more frequent than interval unit 'day'. If this is intentional, set allow_partials to True.", ): load_sql_based_model( d.parse("MODEL (name db.table, interval_unit Day, cron '@hourly'); SELECT a FROM tbl;") ) +def test_interval_unit_larger_than_cron_period(): + # The interval unit can be larger than the cron period if allow_partials is True + model = load_sql_based_model( + d.parse( + "MODEL (name db.table, interval_unit day, cron '@hourly', allow_partials TRUE); SELECT a FROM tbl;" + ) + ) + assert model.interval_unit == IntervalUnit.DAY + assert model.cron == "@hourly" + assert model.allow_partials + + with pytest.raises( + ConfigError, + match=r"Cron '@hourly' cannot be more frequent than interval unit 'day'. If this is intentional, set allow_partials to True.", + ): + load_sql_based_model( + d.parse("MODEL (name db.table, interval_unit day, cron '@hourly'); SELECT a FROM tbl;") + ) + + with pytest.raises( + ConfigError, + match=r"Cron '@hourly' cannot be more frequent than interval unit 'day'. If this is intentional, set allow_partials to True.", + ): + load_sql_based_model( + d.parse( + "MODEL (name db.table, interval_unit day, cron '@hourly', allow_partials FALSE); SELECT a FROM tbl;" + ) + ) + + def test_model_physical_properties() -> None: # Validate python model table properties @model(