Skip to content

Commit eb9f77f

Browse files
authored
Fix: Apply empty backfill only to snapshots that have been selected for backfill within a plan (#4163)
1 parent 1c1e9ad commit eb9f77f

2 files changed

Lines changed: 57 additions & 0 deletions

File tree

sqlmesh/core/plan/evaluator.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,9 @@ def _backfill(
204204
if plan.empty_backfill:
205205
intervals_to_add = []
206206
for snapshot in snapshots_by_name.values():
207+
if not snapshot.evaluatable or not plan.is_selected_for_backfill(snapshot.name):
208+
# Skip snapshots that are not evaluatable or not selected for backfill.
209+
continue
207210
intervals = [
208211
snapshot.inclusive_exclusive(plan.start, plan.end, strict=False, expand=False)
209212
]

tests/core/test_integration.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3938,9 +3938,63 @@ def test_empty_backfill(init_and_plan_context: t.Callable):
39383938

39393939
snapshots = plan.snapshots
39403940
for snapshot in snapshots.values():
3941+
if not snapshot.intervals:
3942+
continue
39413943
assert snapshot.intervals[-1][1] <= to_timestamp("2023-01-08")
39423944

39433945

3946+
@time_machine.travel("2023-01-08 15:00:00 UTC")
3947+
def test_empty_backfill_new_model(init_and_plan_context: t.Callable):
3948+
context, plan = init_and_plan_context("examples/sushi")
3949+
context.apply(plan)
3950+
3951+
new_model = load_sql_based_model(
3952+
d.parse(
3953+
"""
3954+
MODEL (
3955+
name memory.sushi.new_model,
3956+
kind FULL,
3957+
cron '0 8 * * *',
3958+
start '2023-01-01',
3959+
);
3960+
3961+
SELECT 1 AS one;
3962+
"""
3963+
)
3964+
)
3965+
new_model_name = context.upsert_model(new_model).fqn
3966+
3967+
with time_machine.travel("2023-01-09 00:00:00 UTC"):
3968+
plan = context.plan_builder("dev", skip_tests=True, empty_backfill=True).build()
3969+
assert plan.end == to_datetime("2023-01-09")
3970+
assert plan.missing_intervals
3971+
assert plan.empty_backfill
3972+
assert not plan.requires_backfill
3973+
3974+
context.apply(plan)
3975+
3976+
for model in context.models.values():
3977+
if model.is_seed or model.kind.is_symbolic:
3978+
continue
3979+
row_num = context.engine_adapter.fetchone(f"SELECT COUNT(*) FROM sushi__dev.new_model")[
3980+
0
3981+
]
3982+
assert row_num == 0
3983+
3984+
plan = context.plan_builder("prod", skip_tests=True).build()
3985+
assert not plan.requires_backfill
3986+
assert not plan.missing_intervals
3987+
3988+
snapshots = plan.snapshots
3989+
for snapshot in snapshots.values():
3990+
if not snapshot.intervals:
3991+
continue
3992+
elif snapshot.name == new_model_name:
3993+
assert snapshot.intervals[-1][1] == to_timestamp("2023-01-09")
3994+
else:
3995+
assert snapshot.intervals[-1][1] <= to_timestamp("2023-01-08")
3996+
3997+
39443998
@time_machine.travel("2023-01-08 15:00:00 UTC")
39453999
def test_dbt_requirements(sushi_dbt_context: Context):
39464000
assert set(sushi_dbt_context.requirements) == {"dbt-core", "dbt-duckdb"}

0 commit comments

Comments
 (0)