Skip to main content
Change detection is selection-aware. When you scope a run with --select, SQLBuild only runs (and only displays) the resources you selected, but it still reasons about the whole graph to keep the result honest. The key case it handles: a selected model whose upstream changed but is not in the selection.

Only selected resources appear in the plan

For a scoped run like sqb dbt build --select agg_daily_revenue, the plan shows only the selected resources, not their passive upstream closure. SQLBuild still walks upstreams internally for change propagation (a selected model flips to run when an upstream changed), but those passive upstreams are not listed as plan entries or counted in the header. --full-refresh is likewise scoped to the selected models, not the expanded upstream closure.

Stale warnings instead of silent partial rebuilds

If a selected model has an upstream that changed but is outside the selection, rebuilding the selected model alone would run it on top of a stale upstream and silently produce a result that looks current but isn’t. SQLBuild does not do that. It leaves the selected model current (it is not rebuilt) and emits a stale warning naming the changed upstreams, with the selector you can use to incorporate them. Suppose stg_orders (upstream) changed, and you select only the downstream agg_daily_revenue:
The model stays current rather than being rebuilt on a stale input, and the warning tells you exactly which upstreams changed and how to pull them in.

Incorporating the changed upstreams

Use a closure selector to include the changed upstreams in the run. With +agg_daily_revenue, SQLBuild pulls in the changed stg_orders, cascades the change through the intermediate models, and rebuilds:

Seeds follow the same rule

Seed changes are tracked the same selection-aware way. A changed seed that is outside the current selection does not trigger a partial rebuild of its dependents; instead the dependents are left current and a stale warning is emitted, exactly as for models. This keeps a scoped run from quietly building on a seed that the run didn’t reload.

Why this matters

A run that reports success but silently built a model on stale inputs is a correctness hazard - the data looks fresh but isn’t. Surfacing staleness as an explicit warning (and refusing the misleading partial rebuild) keeps scoped runs honest: you either get a result built on current inputs, or a clear warning telling you it would not be, with the fix.