Skip to content

Commit dda0290

Browse files
committed
refactor: key promotion snapshots by name once per promotion
Build the name-keyed snapshots dict once in SnapshotEvaluator.promote instead of once per promoted view, keep the TableMapping cache across copy(), and pin the number of replace_tables calls made during promotion. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Rwe8v9iP3iGKVygBfPEZaU Signed-off-by: mday-io <mdaytn@gmail.com>
1 parent 9ab6474 commit dda0290

4 files changed

Lines changed: 15 additions & 9 deletions

File tree

‎sqlmesh/core/renderer.py‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ def normalized_keys(self, dialect: DialectType) -> t.Dict[str, str]:
6565
self._normalized_keys[dialect] = normalized_keys
6666
return normalized_keys
6767

68+
def copy(self) -> TableMapping:
69+
# dict.copy() would return a plain dict and lose the cache.
70+
return TableMapping(self)
71+
6872
def __setitem__(self, key: str, value: str) -> None:
6973
self._normalized_keys.clear()
7074
super().__setitem__(key, value)

‎sqlmesh/core/snapshot/evaluator.py‎

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,8 @@ def promote(
312312
self._get_virtual_data_objects(target_snapshots, environment_naming_info)
313313

314314
deployability_index = deployability_index or DeployabilityIndex.all_deployable()
315+
# Renderers look snapshots up by model name, not by SnapshotId.
316+
snapshots_by_name = {s.name: s for s in (snapshots or {}).values()}
315317
with self.concurrent_context():
316318
concurrent_apply_to_snapshots(
317319
target_snapshots,
@@ -320,7 +322,7 @@ def promote(
320322
start=start,
321323
end=end,
322324
execution_time=execution_time,
323-
snapshots=snapshots,
325+
snapshots=snapshots_by_name,
324326
table_mapping=table_mapping,
325327
environment_naming_info=environment_naming_info,
326328
deployability_index=deployability_index, # type: ignore
@@ -1260,7 +1262,7 @@ def _promote_snapshot(
12601262
start: t.Optional[TimeLike] = None,
12611263
end: t.Optional[TimeLike] = None,
12621264
execution_time: t.Optional[TimeLike] = None,
1263-
snapshots: t.Optional[t.Dict[SnapshotId, Snapshot]] = None,
1265+
snapshots: t.Optional[t.Dict[str, Snapshot]] = None,
12641266
table_mapping: t.Optional[t.Dict[str, str]] = None,
12651267
) -> None:
12661268
if not snapshot.is_model:
@@ -1284,8 +1286,6 @@ def _promote_snapshot(
12841286
table_mapping=table_mapping,
12851287
runtime_stage=RuntimeStage.PROMOTING,
12861288
)
1287-
# Renderers look snapshots up by model name, not by SnapshotId.
1288-
snapshots_by_name = {s.name: s for s in (snapshots or {}).values()}
12891289

12901290
with (
12911291
adapter.transaction(),
@@ -1296,15 +1296,13 @@ def _promote_snapshot(
12961296
view_name=view_name,
12971297
model=snapshot.model,
12981298
environment=environment_naming_info.name,
1299-
snapshots=snapshots_by_name,
1299+
snapshots=snapshots,
13001300
snapshot=snapshot,
13011301
**render_kwargs,
13021302
)
13031303

13041304
adapter.execute(
1305-
snapshot.model.render_on_virtual_update(
1306-
snapshots=snapshots_by_name, **render_kwargs
1307-
)
1305+
snapshot.model.render_on_virtual_update(snapshots=snapshots, **render_kwargs)
13081306
)
13091307

13101308
if on_complete is not None:

‎tests/core/test_model.py‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10285,6 +10285,9 @@ def test_table_mapping_normalized_keys(dialect: str):
1028510285
# Normalization happens once per dialect.
1028610286
assert table_mapping.normalized_keys(dialect) is normalized
1028710287

10288+
assert isinstance(table_mapping.copy(), TableMapping)
10289+
assert table_mapping.copy() == table_mapping
10290+
1028810291
# Every mutation invalidates the cache.
1028910292
table_mapping["db.b"] = "view_b"
1029010293
assert "db.b" in table_mapping.normalized_keys("duckdb")

‎tests/core/test_snapshot_evaluator.py‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5762,6 +5762,7 @@ def test_promote_resolves_this_model_with_single_mapping_entry(
57625762
)
57635763

57645764
assert adapter_mock.create_view.call_count == 20
5765-
assert spy.call_count >= 20
5765+
# One call per view, to resolve `this_model`.
5766+
assert spy.call_count == 20
57665767
for call in spy.call_args_list:
57675768
assert len(call.args[1]) == 1

0 commit comments

Comments
 (0)