Implementation:TobikoData Sqlmesh SnapshotEvaluator Promote
| Knowledge Sources | |
|---|---|
| Domains | Data_Engineering, Deployment |
| Last Updated | 2026-02-07 00:00 GMT |
Overview
Concrete promotion method for updating virtual layer views to point to snapshot physical tables, provided by the SnapshotEvaluator class.
Description
The SnapshotEvaluator.promote method implements SQLMesh's virtual layer mechanism by creating or updating database views that point to physical snapshot tables. This method receives a collection of snapshots to promote and generates CREATE OR REPLACE VIEW statements for each, redirecting environment-specific view names (like "prod.orders") to snapshot-specific physical table names (like "sqlmesh__prod.orders__a8f3k2").
The method handles infrastructure preparation (creating catalogs and schemas), coordinates promotion across multiple database gateways, respects deployability constraints (only promoting snapshots with complete data), executes view creation concurrently where safe, and invokes completion callbacks for progress tracking. By updating view definitions rather than moving data, promotion is atomic and instant from a query perspective, enabling zero-downtime deployments and instant rollbacks.
Usage
This method is called internally by Context.apply() during the promotion phase after backfills complete. It is typically not called directly by user code, but understanding it is essential for grasping SQLMesh's virtual environment architecture. The method is the core mechanism enabling features like isolated development environments, instant rollbacks, and cost-efficient environment branching without data duplication.
Code Reference
Source Location
- Repository: sqlmesh
- File: sqlmesh/core/snapshot/evaluator.py
- Class: SnapshotEvaluator
- Method: promote (lines 267-331)
Signature
def promote(
self,
target_snapshots: t.Iterable[Snapshot],
environment_naming_info: EnvironmentNamingInfo,
deployability_index: t.Optional[DeployabilityIndex] = None,
start: t.Optional[TimeLike] = None,
end: t.Optional[TimeLike] = None,
execution_time: t.Optional[TimeLike] = None,
snapshots: t.Optional[t.Dict[SnapshotId, Snapshot]] = None,
table_mapping: t.Optional[t.Dict[str, str]] = None,
on_complete: t.Optional[t.Callable[[SnapshotInfoLike], None]] = None,
) -> None:
Import
# Typically not imported directly; used internally by Context
from sqlmesh.core.snapshot.evaluator import SnapshotEvaluator
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| target_snapshots | Iterable[Snapshot] | Yes | Snapshots to promote by creating/updating views |
| environment_naming_info | EnvironmentNamingInfo | Yes | Environment-specific naming (catalog, schema, suffix) |
| deployability_index | DeployabilityIndex | No | Index indicating which snapshots have complete data |
| start | TimeLike | No | Start time for execution context |
| end | TimeLike | No | End time for execution context |
| execution_time | TimeLike | No | Execution timestamp reference |
| snapshots | Dict[SnapshotId, Snapshot] | No | Full snapshot mapping for dependency resolution |
| table_mapping | Dict[str, str] | No | Custom table name mappings |
| on_complete | Callable | No | Callback invoked after each successful promotion |
Outputs
| Name | Type | Description |
|---|---|---|
| None | None | Method returns None; side effects are view creation in database |
Usage Examples
Internal Context Usage
# This is how promote is called internally during Context.apply()
# Users typically don't call this directly
from sqlmesh.core.context import Context
context = Context(paths="project")
# This internally calls SnapshotEvaluator.promote during apply
plan = context.plan("prod")
context.apply(plan) # Promotion happens here
Understanding Virtual Layer
# What promote does conceptually:
#
# Before promotion:
# - Physical table exists: sqlmesh__prod.orders__a8f3k2 (with data)
# - View points to old version: prod.orders -> sqlmesh__prod.orders__old123
#
# During promotion:
# - Creates/updates view: CREATE OR REPLACE VIEW prod.orders AS SELECT * FROM sqlmesh__prod.orders__a8f3k2
#
# After promotion:
# - View now points to new version: prod.orders -> sqlmesh__prod.orders__a8f3k2
# - Queries to prod.orders instantly see new data
# - No downtime, no data movement
from sqlmesh.core.context import Context
context = Context(paths="project")
plan = context.plan("prod")
# Promotion makes changes visible atomically
context.apply(plan)
Multi-Environment Promotion
# Promote same models to multiple environments
# Each environment gets views pointing to appropriate snapshots
from sqlmesh.core.context import Context
context = Context(paths="project")
# Dev environment: models under active development
dev_plan = context.plan("dev_alice")
context.apply(dev_plan) # Promotes to dev_alice schema
# Staging environment: testing pre-production
staging_plan = context.plan("staging")
context.apply(staging_plan) # Promotes to staging schema
# Production environment: stable versions
prod_plan = context.plan("prod", forward_only=True)
context.apply(prod_plan) # Promotes to prod schema
# Result:
# - dev_alice.orders -> points to dev version snapshot
# - staging.orders -> points to staging version snapshot
# - prod.orders -> points to production version snapshot
# - Unchanged models share same physical tables across environments
Rollback via Re-Promotion
# Rollback works by re-promoting previous snapshots
# This updates views to point back to old physical tables
from sqlmesh.core.context import Context
context = Context(paths="project")
# Deploy new version
new_plan = context.plan("prod")
context.apply(new_plan)
# Issue discovered, need to rollback
# Create plan that reverts to previous state
# (In practice, use context.rollback() or revert code changes)
# The rollback re-promotes old snapshots
# Views instantly point back to previous physical tables
# No data loss, instant rollback
Progress Tracking
# on_complete callback tracks promotion progress
# Useful for custom monitoring and logging
from sqlmesh.core.context import Context
context = Context(paths="project")
promoted_count = 0
def track_promotion(snapshot_info):
global promoted_count
promoted_count += 1
print(f"Promoted: {snapshot_info.name} ({promoted_count} total)")
# This callback is passed internally during apply
plan = context.plan("prod")
context.apply(plan) # Promotion callbacks fire during this
print(f"Total promotions: {promoted_count}")
Environment Isolation
# Virtual layer enables isolated environments without data duplication
from sqlmesh.core.context import Context
context = Context(paths="project")
# Create isolated dev environment
dev_plan = context.plan("dev_feature_x", create_from="prod")
context.apply(dev_plan)
# Result:
# - Unchanged models: dev_feature_x views point to prod physical tables (shared)
# - Modified models: dev_feature_x views point to new physical tables (isolated)
# - Cost: only pay for storage/compute of changed models
# - Safety: dev changes don't affect prod queries