11. Why use ref() in dbt
In dbt, why do you write {{ ref('stg_orders') }} instead of a hard-coded table name?
- A.It makes the SQL run faster on the warehouse
- B.It encrypts the table name
- C.It builds the dependency graph so models run in the right order, and resolves to the right schema per environment
- D.It is required only for Python models
Show answer
Answer: C. It builds the dependency graph so models run in the right order, and resolves to the right schema per environment
ref() tells dbt that this model depends on stg_orders, so dbt builds a DAG, runs models in order, and shows lineage. It also resolves to the correct database and schema for dev, CI or prod, avoiding hard-coded names.
12. Running a dbt project in Airflow
A BashOperator runs dbt build for 120 models. When one model fails, the whole task must rerun. What gives one Airflow task per dbt model instead?
- A.Setting retries=120 on the BashOperator
- B.Using astronomer-cosmos to render the dbt project
- C.Using a pool with 120 slots
- D.Splitting the dbt project into 120 repos
Show answer
Answer: B. Using astronomer-cosmos to render the dbt project
Cosmos reads the dbt project and builds a task group with a task for each model (and its tests), keeping dbt's dependency order. You can then retry or clear a single model. A single BashOperator only sees one pass or fail for everything.
13. Warning before failing on stale sources
In dbt you want a warning if a source has not loaded new rows for 12 hours, and an error after 24. What do you configure?
- A.A not_null test on the source id
- B.freshness: warn_after and error_after
- C.An incremental model with a 12-hour filter
- D.A unique test on the loaded_at column
Show answer
Answer: B. freshness: warn_after and error_after
dbt source freshness compares the newest loaded_at_field value with the current time and reports warn or error based on warn_after and error_after. Run dbt source freshness before models so stale inputs are caught early.
14. Keeping history of a source table
A source customers table is overwritten in place, so past addresses are lost. Which dbt feature records each change over time as SCD type 2 rows?
- A.An incremental model with append
- B.A seed
- C.A snapshot
- D.A source freshness check
Show answer
Answer: C. A snapshot
dbt snapshots compare the current source with what was stored, and for changed rows close the old version and insert a new one with dbt_valid_from and dbt_valid_to. Run them on a schedule, because changes between runs are not captured.
15. Updated rows in an incremental model
An incremental dbt model loads orders changed in the last day. An order's status changes from packed to shipped, so it appears again. What config makes dbt update the existing row instead of adding a second one?
- A.materialized='view'
- B.full_refresh=false
- C.unique_key='order_id'
- D.tags=['orders']
Show answer
Answer: C. unique_key='order_id'
With a unique_key, warehouses that support it use a merge (or delete+insert) strategy: rows with a matching key are updated, new keys are inserted. Without a unique_key, many adapters just append, so the changed order shows up twice.
16. Selecting a model and its parents
What does dbt run --select +fct_orders run?
- A.fct_orders and every model downstream of it
- B.Only fct_orders
- C.Every model in the project except fct_orders
- D.fct_orders and every model it depends on upstream
Show answer
Answer: D. fct_orders and every model it depends on upstream
A + before a model name selects its ancestors, the models it depends on, plus the model itself. A + after the name (fct_orders+) selects its descendants. You can combine them (+fct_orders+) or limit depth, such as 1+fct_orders.
17. Smaller data in development
Developers want models to read only the last 7 days of events in dev, but all data in prod. What can the model check?
- A.target.name, as in target.name == 'dev'
- B.The model's file name
- C.The seed folder
- D.The number of rows in the source table
Show answer
Answer: A. target.name, as in target.name == 'dev'
target holds details of the active connection profile, such as name, schema and type. Wrapping a date filter in {% if target.name == 'dev' %} limits data in development and keeps production complete. It saves warehouse cost during development.
18. The same check on many columns
Thirty columns across models must never be negative. What is the dbt way to reuse one check?
- A.Write thirty singular tests
- B.Add a CHECK constraint in a seed file
- C.Use dbt snapshot on each column
- D.Write one custom generic test
Show answer
Answer: D. Write one custom generic test
A generic test is a parameterised test block taking model and column_name. Once defined, you list it under any column in YAML, just like unique or not_null. dbt_utils and dbt-expectations already ship many such tests.
19. Tolerating a few bad rows
A not_null test on a phone column fails on a handful of legacy rows. The team wants a warning under 100 failures and an error above that. Which configs do this?
- A.severity: warn, error_if: '>100'
- B.enabled: false
- C.store_failures: true on its own
- D.limit: 100
Show answer
Answer: A. severity: warn, error_if: '>100'
Tests support severity plus warn_if and error_if thresholds on the failure count. With severity warn and error_if '>100', small numbers of failures warn while a large jump still fails the run. Disabling the test would hide real regressions.
20. Seeing which rows failed a test
A dbt test fails in production and the team wants to inspect the exact failing rows afterwards. What config helps?
- A.materialized: ephemeral
- B.store_failures: true
- C.full_refresh: true
- D.persist_docs: true
Show answer
Answer: B. store_failures: true
With store_failures, dbt writes the failing rows of each test to a table in an audit schema. You can query it after the run to see exactly which records broke the rule. It adds a little cost, so many teams turn it on for key tests only.
21. Permissions lost after each rebuild
Every time dbt rebuilds a table, the analyst role loses SELECT on it and dashboards fail. What is the cleanest fix in dbt?
- A.Ask a DBA to grant access by hand after every run
- B.Switch the model to ephemeral
- C.Run dbt only once a month
- D.Set the grants config, e.g. grants: {select: ['analyst']}
Show answer
Answer: D. Set the grants config, e.g. grants: {select: ['analyst']}
Rebuilding a table with CREATE OR REPLACE can drop its existing grants. dbt's grants config applies the listed privileges each time the model is built, so access stays correct. Post-hooks with GRANT statements were the older way.