Skip to content

Commit 913414d

Browse files
authored
Fix: Deployability of a child snapshot when its parent snapshot is indirect non-breaking without intervals (#5340)
1 parent cc2e1f1 commit 913414d

File tree

2 files changed

+44
-9
lines changed

2 files changed

+44
-9
lines changed

sqlmesh/core/snapshot/definition.py

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1644,6 +1644,7 @@ def create(
16441644
snapshot.is_valid_start(start, snapshot_start) if start is not None else True
16451645
)
16461646

1647+
children_deployable = is_valid_start and not has_auto_restatement
16471648
if (
16481649
snapshot.is_forward_only
16491650
or snapshot.is_indirect_non_breaking
@@ -1660,15 +1661,9 @@ def create(
16601661
):
16611662
# This snapshot represents what's currently deployed in prod.
16621663
representative_shared_version_ids.add(node)
1663-
1664-
# A child can still be deployable even if its parent is not
1665-
children_deployable = (
1666-
is_valid_start
1667-
and not (
1668-
snapshot.is_paused and (snapshot.is_forward_only or is_forward_only_model)
1669-
)
1670-
and not has_auto_restatement
1671-
)
1664+
else:
1665+
# If the parent is not representative then its children can't be deployable.
1666+
children_deployable = False
16721667
else:
16731668
children_deployable = False
16741669
if not snapshots[node].is_paused:

tests/core/test_integration.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1347,6 +1347,46 @@ def test_indirect_non_breaking_change_after_forward_only_in_dev(init_and_plan_co
13471347
)
13481348

13491349

1350+
@time_machine.travel("2023-01-08 15:00:00 UTC")
1351+
def test_changes_downstream_of_indirect_non_breaking_snapshot_without_intervals(
1352+
init_and_plan_context: t.Callable,
1353+
):
1354+
context, plan = init_and_plan_context("examples/sushi")
1355+
context.apply(plan)
1356+
1357+
# Make a breaking change first but don't backfill it
1358+
model = context.get_model("sushi.orders")
1359+
model = model.copy(update={"stamp": "force new version"})
1360+
context.upsert_model(model)
1361+
plan_builder = context.plan_builder(
1362+
"dev", skip_backfill=True, skip_tests=True, no_auto_categorization=True
1363+
)
1364+
plan_builder.set_choice(context.get_snapshot(model), SnapshotChangeCategory.BREAKING)
1365+
context.apply(plan_builder.build())
1366+
1367+
# Now make a non-breaking change to the same snapshot.
1368+
model = model.copy(update={"stamp": "force another new version"})
1369+
context.upsert_model(model)
1370+
plan_builder = context.plan_builder(
1371+
"dev", skip_backfill=True, skip_tests=True, no_auto_categorization=True
1372+
)
1373+
plan_builder.set_choice(context.get_snapshot(model), SnapshotChangeCategory.NON_BREAKING)
1374+
context.apply(plan_builder.build())
1375+
1376+
# Now make a change to a model downstream of the above model.
1377+
downstream_model = context.get_model("sushi.top_waiters")
1378+
downstream_model = downstream_model.copy(update={"stamp": "yet another new version"})
1379+
context.upsert_model(downstream_model)
1380+
plan = context.plan_builder("dev", skip_tests=True).build()
1381+
1382+
# If the parent is not representative then the child cannot be deployable
1383+
deployability_index = plan.deployability_index
1384+
assert not deployability_index.is_representative(
1385+
context.get_snapshot("sushi.waiter_revenue_by_day")
1386+
)
1387+
assert not deployability_index.is_deployable(context.get_snapshot("sushi.top_waiters"))
1388+
1389+
13501390
@time_machine.travel("2023-01-08 15:00:00 UTC", tick=True)
13511391
def test_metadata_change_after_forward_only_results_in_migration(init_and_plan_context: t.Callable):
13521392
context, plan = init_and_plan_context("examples/sushi")

0 commit comments

Comments
 (0)