What you will be able to do
- Say which resource types
dbt run,dbt test,dbt seed,dbt snapshotanddbt buildact on, and which they leave alone - Predict how
dbt buildorders resources, and which ones it skips when a test or model fails - Choose the right command and flags (
--select,--full-refresh,--empty,--vars) for a given change
Key concept
dbt build as one DAG-ordered pass — dbt build runs models, tests tests, seeds seeds and snapshots snapshots in a single run, following the dependency graph. Because tests run between resources, a failing upstream test can stop the resources that depend on it from being built.
1.dbt run materializes models and nothing else
A dbt project holds several kinds of resource: models, tests, seeds and snapshots. Each kind has its own command. Using the wrong one fails quietly: the command succeeds, but the thing you meant to refresh never ran. The narrowest of these commands is dbt run. It only applies to models and doesn't run tests, snapshots, seeds or any other resource type.
dbt run executes the compiled SQL of your models against the current target, and builds each model with its configured materialization. Models run in the order of the dependency graph built during compilation. dbt runs models on several threads at once to shorten the run, but never in a way that breaks that order. When a model replaces an earlier version, dbt first builds it under a temporary name. It then drops the old version and renames the new one inside a single transaction, on adapters that support transactions. That keeps downtime short.
The --full-refresh flag (short form -f) makes dbt treat incremental models as table models, and is_incremental() returns false for every model. Use it when an incremental model's schema has changed, or when new logic means its whole history must be reprocessed. Picking the strategy that avoids those rebuilds is covered in [incremental strategy selection](lesson:1.11). dbt run also accepts --empty for schema-only dry runs, which is the subject of [dry runs with --empty](lesson:1.12).
Checkpoint 1 of 8· Check yourself
A developer edits a staging model, adds a new CSV to the seeds folder, and then runs only dbt run. What has happened afterwards?
dbt run only handles models. Loading the seed needs dbt seed and running tests needs dbt test, or you can do all of it with dbt build.
“The dbt run command only applies to models. It doesn't run tests, snapshots, seeds, or other resource types.”Source: docs.getdbt.com
Checkpoint 2 of 8· Exam question
An analytics engineering team has a project with seeds, snapshots, models, and schema tests. Before deploying to production, they want a single command that builds seeds, then snapshots, then models, then runs applicable tests, all in dependency order, automatically skipping downstream nodes if an upstream test fails. Which command should they run?
Correct answer: A — Run `dbt build`, letting dbt sequence seeds, snapshots, models, and tests together in one DAG pass.
- A. `dbt build` is the single command that processes seeds, snapshots, models, and their tests together in DAG order, skipping a node's downstream dependents when one of its tests fails. This matches the requirement for one command that sequences all four resource types with automatic failure propagation.
- B. `dbt run` only materializes models and never touches seeds or snapshots, so this two-step sequence would silently skip loading reference data and capturing history before the models run. It also separates the test pass from materialization, so a failure does not automatically block a downstream model from being built in the same invocation.
- C. This sequence never invokes `dbt test` at all, so no tests run and `dbt docs generate` cannot confirm anything about test results — it only compiles documentation metadata. It also requires three separate manual commands instead of one DAG-ordered pass.
- D. `dbt compile` only renders SQL without executing anything against the warehouse, so it builds nothing on its own. Manually triggering each resource individually loses the automatic DAG ordering and failure propagation that the team specifically wants.
Sources1
2.dbt test checks resources that already exist
dbt test checks resources; it builds nothing. It runs data tests defined on models, sources, snapshots and seeds, and unit tests defined on SQL models. It expects those resources to have been created already by the right command. After you edit a model, you have to run or build it before its data tests say anything about the new logic.
Use selection to narrow which tests run. The test_type selector separates unit tests from data tests, and can split data tests further into singular and generic ones. A comma combines two conditions, so one_specific_model,test_type:unit runs only that model's unit tests. Writing each kind of test is covered in [data and unit tests](lesson:5.1).
# run data and unit tests
dbt test
# run only data tests
dbt test --select test_type:data
# run only unit tests
dbt test --select test_type:unitCheckpoint 3 of 8· Fill the gap
Which selector limits dbt test to unit tests only?
# run only unit tests
dbt test --select ? test_type:unit selects unit tests. test_type:singular and test_type:generic are both subsets of data tests.
Sources2
3.dbt seed loads CSV reference data
Seeds are small, version-controlled CSV files kept in the project: country codes, region mappings, a list of business-defined categories. dbt seed loads them into the warehouse as tables. Downstream models then reference those tables like any other, and you rerun dbt seed whenever a CSV changes. Seed settings, such as which directories hold seed files and how columns are interpreted, live in dbt_project.yml.
# Run all seeds
dbt seed
# Run one seed
dbt seed --select "country_codes"
# Rebuild selected seeds from scratch
dbt seed --select "country_codes state_codes" --full-refresh--full-refresh forces a clean reload instead of an incremental update. You need it when the seed's structure changes, for example a renamed column or a changed type, and when environments must behave the same way after a seed change. --empty does the opposite: it creates the seed table with column names and types taken from the CSV, but inserts zero rows. In development or CI, that gives downstream models and unit tests the table structure they need without the cost of loading the data.
Checkpoint 4 of 8· Check yourself
You renamed a column in country_codes.csv and the warehouse table must reflect the new structure. Which command fits best?
A change to seed structure calls for a full reload. --empty builds the structure but loads no rows, and dbt run doesn't touch seeds.
“You have changed the seed structure (for example, column names or types)”Source: docs.getdbt.com
Sources3
4.dbt snapshot captures change history on a schedule
dbt snapshot runs the snapshots defined in your project. They record changes to source data over time as type-2 slowly changing dimensions. A snapshot only captures what the source looks like at the moment it runs, so the command belongs on a schedule, daily for example. How to define a snapshot (its strategy and unique_key) is covered in [snapshots in YAML](lesson:1.10). The command only has to find the snapshots and run them.
dbt looks for snapshots in the directories listed under snapshot-paths in dbt_project.yml, which defaults to snapshots/. --select and --exclude choose which snapshots run. --vars supplies values that the snapshot SQL reads through var().
dbt snapshot --select my_snapshot --vars '{"cutoff_date": "2026-01-01"}'--full-refresh behaves differently here than anywhere else. Snapshots ignore both the full_refresh config and the --full-refresh flag. dbt snapshot --full-refresh, or a dbt build --full-refresh that includes a snapshot, runs the snapshot as normal. It never drops or recreates the snapshot table, so the history already recorded is preserved.
Checkpoint 5 of 8· Check yourself
A snapshot has collected two years of history. Someone runs dbt snapshot --full-refresh. What happens to the snapshot table?
Snapshots ignore --full-refresh. The run proceeds as normal and the table is neither dropped nor recreated.
“it won't drop or recreate the snapshot table, so existing snapshot history is preserved.”Source: docs.getdbt.com
Sources4
5.dbt build runs everything in DAG order and skips on failure
dbt build combines the other four commands into one pass. It runs models, tests tests, snapshots snapshots and seeds seeds, for the selected resources or the whole project, and writes a single manifest and a single run results artifact covering all of them.
| Command | Acts on | Leaves alone |
|---|---|---|
| dbt run | Models | Tests, seeds, snapshots |
| dbt test | Data tests on models, sources, snapshots and seeds; unit tests on SQL models | Building any resource |
| dbt seed | CSV files in seed-paths | Models, tests, snapshots |
| dbt snapshot | Snapshots in snapshot-paths | Models, tests, seeds |
| dbt build | Models, tests, snapshots and seeds, in DAG order | Nothing among those four types |
18:49:43 | 1 of 7 START seed file dbt_jcohen.my_seed............................ [RUN]
18:49:43 | 1 of 7 OK loaded seed file dbt_jcohen.my_seed........................ [INSERT 2 in 0.09s]
18:49:43 | 2 of 7 START view model dbt_jcohen.my_model.......................... [RUN]
18:49:43 | 2 of 7 OK created view model dbt_jcohen.my_model..................... [CREATE VIEW in 0.12s]
18:49:43 | 3 of 7 START test not_null_my_seed_id................................ [RUN]
18:49:43 | 3 of 7 PASS not_null_my_seed_id...................................... [PASS in 0.05s]Running tests between resources is what makes build more than shorthand for four commands. A failing test on model_a causes model_b, which depends on it, to skip, so bad data stops spreading at the point it was detected. Run dbt run and then dbt test instead, and every model is already built before the first test executes.
Two settings loosen this gate. Setting a test's severity or thresholds to warn instead of error means its failures no longer cause skips. For model failures, the default is that a failed model skips everything downstream. on_error: continue on a model lets its downstream models run even when that model fails.
Unit tests act as a gate as well. For each SQL model, build runs its unit tests first, then builds the model, then runs its data tests. A model whose unit tests fail is never built, which saves warehouse spend.
Checkpoint 6 of 8· Put it in order
Put the steps dbt build takes for a SQL model with unit tests and data tests in order.
- 1.Unit tests run on the SQL model
- 2.Data tests run on the model
- 3.The model is materialized
Unit tests run before the model is built, so the warehouse only spends on building it if they pass. Data tests check the built table afterwards.
“This saves on warehouse spend as the model will only be materialized if the unit tests pass successfully.”Source: docs.getdbt.com
Selection uses --select and --exclude, plus --resource-type as a final filter. Tests are included indirectly: dbt build -s model_a both runs and tests model_a. It picks up every test that depends directly on that model, as long as the test doesn't also depend on another parent that wasn't selected. build accepts the flags of run, test, snapshot and seed. A shared flag such as --full-refresh applies to every selected resource type that supports it, so models and seeds are both fully refreshed.
Checkpoint 7 of 8· Check yourself
A project has an incremental model, a seed and a snapshot. What does dbt build --full-refresh do to them?
Shared flags apply to every selected type that supports them, so models and seeds are fully refreshed. Snapshots ignore the flag.
“build will use the same value for all selected resource types that support it”Source: docs.getdbt.com
Checkpoint 8 of 8· Exam question
A team defines the snapshot below and runs `dbt snapshot`. The run fails with an error stating that dbt cannot uniquely identify rows to compare between snapshot runs. ```yaml snapshots: - name: orders_snapshot relation: source('jaffle_shop', 'orders') config: schema: snapshots strategy: timestamp updated_at: updated_at ``` Which required configuration key is missing from this snapshot definition?
Correct answer: A — unique_key
- A. `unique_key` is a required field for every snapshot regardless of strategy, because dbt uses it to match a row in the source against its corresponding row in the snapshot table on each run. Without it, dbt has no way to tell which existing snapshot row a given source row should be compared against, which is exactly the error described.
- B. `check_cols` is only required when `strategy` is set to `check`, not `timestamp`. This snapshot already declares `strategy: timestamp` with an `updated_at` column, so `check_cols` is irrelevant here and adding it would not resolve the row-identification error.
- C. `dbt_valid_to_current` is an optional setting that controls what value is written to `dbt_valid_to` for currently valid rows; it does not affect how dbt matches rows between runs. Omitting it only changes the null-vs-sentinel value used for open records, not row identification.
- D. `hard_deletes` is an optional setting that controls how dbt handles rows removed from the source table, such as marking them invalidated or inserting a new deleted-record row. It has no bearing on how dbt identifies which row corresponds to which across runs.
Sources5
Exam traps
Each one states something that sounds right. Open it to see what is actually true.
1.
dbt runalso runs the tests and loads the seeds for the models it builds.Why is that wrong?dbt runonly applies to models. Tests, seeds and snapshots need their own commands, ordbt build.Covered in dbt run materializes models and nothing else
2.
dbt testbuilds the model first, then tests it.Why is that wrong?dbt testonly runs tests against resources that already exist. Building them is the job of other commands.Covered in dbt test checks resources that already exist
3.
dbt build --full-refreshrebuilds snapshot tables along with the models.Why is that wrong?Snapshots ignore
--full-refreshand thefull_refreshconfig, so their history is preserved.Covered in dbt snapshot captures change history on a schedule
4.In
dbt build, a failing test is only reported, and downstream models still run.Why is that wrong?A test failing at error severity makes downstream resources skip. Only warn severity or thresholds avoid the skip.
Covered in dbt build runs everything in DAG order and skips on failure
Sources
Every claim above is drawn from one of these pages, quoted as it was written on the date shown.
- 1.https://docs.getdbt.com/reference/commands/runOfficial docs
“The dbt run command only applies to models. It doesn't run tests, snapshots, seeds, or other resource types.”
↩︎ dbt run materializes models and nothing else“Models are run in the order defined by the dependency graph generated during compilation.”
↩︎ dbt run materializes models and nothing else“first building each model with a temporary name, then dropping and renaming within a single transaction”
↩︎ dbt run materializes models and nothing else“If you provide the --full-refresh flag to dbt run, dbt will treat incremental models as table models.”
↩︎ dbt run materializes models and nothing else“The dbt run command only applies to models. It doesn't run tests, snapshots, seeds, or other resource types.”
↩︎ Exam trap 1 - 2.https://docs.getdbt.com/reference/commands/testOfficial docs
“dbt test runs data tests defined on models, sources, snapshots, and seeds and unit tests defined on SQL models.”
↩︎ dbt test checks resources that already exist“It expects that you have already created those resources through the appropriate commands.”
↩︎ dbt test checks resources that already exist“It expects that you have already created those resources through the appropriate commands.”
↩︎ Exam trap 2 - 3.https://docs.getdbt.com/reference/commands/seedOfficial docs
“Use seeds for small, version-controlled reference datasets you want to keep alongside your project”
↩︎ dbt seed loads CSV reference data“Use --full-refresh to force a full reload of seed data”
↩︎ dbt seed loads CSV reference data“Use --empty to create seed tables with the correct schema but without loading any data.”
↩︎ dbt seed loads CSV reference data“You have changed the seed structure (for example, column names or types)”
↩︎ Checkpoint - 4.https://docs.getdbt.com/reference/commands/snapshotOfficial docs
“Snapshots record changes to your source data over time by implementing type-2 Slowly Changing Dimensions.”
↩︎ dbt snapshot captures change history on a schedule“Run dbt snapshot on a schedule (for example, daily) to capture changes in your source tables.”
↩︎ dbt snapshot captures change history on a schedule“By default, dbt uses the snapshots/ directory.”
↩︎ dbt snapshot captures change history on a schedule“Snapshots ignore both the full_refresh config and the --full-refresh flag.”
↩︎ Exam trap 3“it won't drop or recreate the snapshot table, so existing snapshot history is preserved.”
↩︎ Checkpoint - 5.https://docs.getdbt.com/reference/commands/buildOfficial docs
“The build task will write a single manifest and a single run results artifact.”
↩︎ dbt build runs everything in DAG order and skips on failure“a test failure will cause those downstream resources to skip entirely”
↩︎ dbt build runs everything in DAG order and skips on failure“Set on_error: continue on a model to allow its downstream models to run even when that model fails.”
↩︎ dbt build runs everything in DAG order and skips on failure“dbt build -s model_a will both run and test model_a”
↩︎ dbt build runs everything in DAG order and skips on failure“In DAG order, for selected resources or an entire project.”
↩︎ Key concept“Don't want a test to cause skipping? Adjust its severity or thresholds to warn instead of error”
↩︎ Exam trap 4“If model_b depends on model_a, and a unique test on model_a fails, then model_b will SKIP.”
↩︎ Prediction“This saves on warehouse spend as the model will only be materialized if the unit tests pass successfully.”
↩︎ Checkpoint“build will use the same value for all selected resource types that support it”
↩︎ Checkpoint