Skip to content

Commit 59ea19a

Browse files
committed
Fix: Unexpected backfill when the parent model's cron is before its child's (#2179)
1 parent beaa5a7 commit 59ea19a

File tree

3 files changed

+51
-6
lines changed

3 files changed

+51
-6
lines changed

sqlmesh/core/snapshot/definition.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -771,7 +771,6 @@ def missing_intervals(
771771
if self.is_symbolic or (self.is_seed and intervals):
772772
return []
773773

774-
execution_time = execution_time or now()
775774
allow_partials = not end_bounded and self.is_model and self.model.allow_partials
776775
start_ts, end_ts = (
777776
to_timestamp(ts)
@@ -785,6 +784,10 @@ def missing_intervals(
785784

786785
interval_unit = self.node.interval_unit
787786

787+
execution_time = execution_time or now()
788+
if end_bounded:
789+
execution_time = min(to_timestamp(execution_time), end_ts)
790+
788791
if not allow_partials:
789792
upper_bound_ts = to_timestamp(
790793
self.node.cron_floor(execution_time) if not ignore_cron else execution_time
@@ -794,9 +797,6 @@ def missing_intervals(
794797
upper_bound_ts = to_timestamp(execution_time)
795798
end_ts = min(end_ts, upper_bound_ts)
796799

797-
if end_bounded:
798-
upper_bound_ts = end_ts
799-
800800
lookback = self.model.lookback if self.is_model else 0
801801

802802
return compute_missing_intervals(

tests/core/test_integration.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,48 @@ def test_hourly_model_with_lookback_no_backfill_in_dev(init_and_plan_context: t.
379379
]
380380

381381

382+
@freeze_time("2023-01-08 00:00:00")
383+
def test_parent_cron_before_child(init_and_plan_context: t.Callable):
384+
context, plan = init_and_plan_context("examples/sushi")
385+
386+
model = context.get_model("sushi.waiter_revenue_by_day")
387+
model = SqlModel.parse_obj(
388+
{
389+
**model.dict(),
390+
"cron": "50 23 * * *",
391+
}
392+
)
393+
context.upsert_model(model)
394+
395+
plan = context.plan("prod", no_prompts=True, skip_tests=True)
396+
context.apply(plan)
397+
398+
top_waiters_model = context.get_model("sushi.top_waiters")
399+
top_waiters_model = add_projection_to_model(t.cast(SqlModel, top_waiters_model), literal=True)
400+
context.upsert_model(top_waiters_model)
401+
402+
snapshot = context.get_snapshot(model, raise_if_missing=True)
403+
top_waiters_snapshot = context.get_snapshot("sushi.top_waiters", raise_if_missing=True)
404+
405+
with freeze_time("2023-01-08 23:55:00"): # Past parent's cron, but before child's
406+
plan = context.plan("dev", no_prompts=True, skip_tests=True)
407+
# Make sure the waiter_revenue_by_day model is not backfilled.
408+
assert plan.missing_intervals == [
409+
SnapshotIntervals(
410+
snapshot_id=top_waiters_snapshot.snapshot_id,
411+
intervals=[
412+
(to_timestamp("2023-01-01"), to_timestamp("2023-01-02")),
413+
(to_timestamp("2023-01-02"), to_timestamp("2023-01-03")),
414+
(to_timestamp("2023-01-03"), to_timestamp("2023-01-04")),
415+
(to_timestamp("2023-01-04"), to_timestamp("2023-01-05")),
416+
(to_timestamp("2023-01-05"), to_timestamp("2023-01-06")),
417+
(to_timestamp("2023-01-06"), to_timestamp("2023-01-07")),
418+
(to_timestamp("2023-01-07"), to_timestamp("2023-01-08")),
419+
],
420+
),
421+
]
422+
423+
382424
@freeze_time("2023-01-08 15:00:00")
383425
def test_forward_only_parent_created_in_dev_child_created_in_prod(
384426
init_and_plan_context: t.Callable,

tests/core/test_snapshot.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -339,10 +339,13 @@ def test_missing_intervals_end_bounded_with_ignore_cron(make_snapshot):
339339
(to_timestamp("2023-01-02"), to_timestamp(end)),
340340
]
341341
assert (
342-
snapshot.missing_intervals(start, end, execution_time=execution_ts, end_bounded=True) == []
342+
snapshot.missing_intervals(
343+
start, to_datetime(end), execution_time=execution_ts, end_bounded=True
344+
)
345+
== []
343346
)
344347
assert snapshot.missing_intervals(
345-
start, end, execution_time=execution_ts, ignore_cron=True, end_bounded=True
348+
start, to_datetime(end), execution_time=execution_ts, ignore_cron=True, end_bounded=True
346349
) == [
347350
(to_timestamp("2023-01-02"), to_timestamp(end)),
348351
]

0 commit comments

Comments
 (0)