📖 Scenario: You work as a data analyst in a company that collects sales data from multiple stores. Each store's raw data is stored in separate source tables in your data warehouse. To keep your data models clean and easy to maintain, you want to follow the one model per source table rule in dbt.This means you will create one dbt model for each source table, transforming the raw data step-by-step.
🎯 Goal: Build dbt models that follow the one model per source table rule by creating a model for each source table and then combining them in a final model.You will start by defining source tables, then create models for each source, and finally create a combined model that joins the data.
📋 What You'll Learn
Define source tables in dbt source configuration
Create one dbt model per source table
Create a final dbt model that joins the individual models
Use simple SQL SELECT statements in models
💡 Why This Matters
🌍 Real World
In real companies, raw data often comes from many tables. Creating one model per source table helps organize transformations clearly and makes debugging easier.
💼 Career
Data analysts and engineers use dbt to build reliable data pipelines. Understanding this rule is key to writing clean, maintainable dbt projects.
Progress0 / 4 steps
1
Define source tables in dbt
In your sources.yml file, define two source tables named store_a_sales and store_b_sales under the source called raw_sales. Each source table should have columns sale_id, product, and amount.
dbt
Hint
Remember to define the source name raw_sales and list both tables store_a_sales and store_b_sales with their columns.
2
Create one model per source table
Create two dbt models named store_a_sales.sql and store_b_sales.sql. Each model should select all columns from its respective source table using the source() function, for example, select * from {{ source('raw_sales', 'store_a_sales') }}.
dbt
Hint
Use the source() function to select all columns from each source table in separate model files.
3
Create a combined model joining the two sources
Create a dbt model named combined_sales.sql that joins the two models store_a_sales and store_b_sales on sale_id. Select sale_id, product from store_a_sales, and amount from both tables with aliases amount_a and amount_b.
dbt
Hint
Use {{ ref('model_name') }} to refer to other models and join them on sale_id.
4
Print the combined sales model SQL
Print the SQL query from the combined_sales.sql model to see the final combined data.
dbt
Hint
Print the final SQL query string exactly as it appears in the combined_sales model.
Practice
(1/5)
1. What is the main reason for following the one model per source table rule in dbt?
easy
A. To avoid using source tables in models
B. To combine multiple source tables into one model
C. To write fewer SQL queries
D. To keep models simple and easy to understand
Solution
Step 1: Understand the rule and its benefits
The rule encourages creating one dbt model for each source table to keep things simple and clear. This approach helps with clarity, debugging, and teamwork by avoiding complex combined models.
Final Answer:
To keep models simple and easy to understand -> Option D
Quick Check:
One model per source table = simplicity [OK]
Hint: One model per source table means simpler, clearer models [OK]
Common Mistakes:
Thinking it means combining tables into one model
Believing it reduces the number of models
Assuming it avoids using source tables
2. Which of the following is the correct way to define a dbt model for a source table named customers?
easy
A. Create a model file named all_data.sql combining all source tables
B. Create a model file named customers.sql with a SELECT from the source table
C. Create a model file named customers.sql but do not select from the source table
D. Create a model file named source_customers.sql without referencing the source
Solution
Step 1: Match model name to source table and reference it
Following the rule, the model file should be named after the source table, here customers.sql. The model should select data from the source table to represent it clearly.
Final Answer:
Create a model file named customers.sql with a SELECT from the source table -> Option B
Quick Check:
Model name = source table name + SELECT from source [OK]
Hint: Model file name matches source table name and selects from it [OK]
Common Mistakes:
Naming model file unrelated to source table
Not selecting from the source table
Combining multiple tables in one model
3. Given this dbt model SQL for source table orders:
select * from {{ source('sales_db', 'orders') }}
What will be the output if the source table has 100 rows?
medium
A. The model will return 100 rows identical to the source table
B. The model will return zero rows
C. The model will return 1 row with aggregated data
D. The model will cause a syntax error
Solution
Step 1: Understand the SQL query and predict output
The query selects all columns and rows from the source table orders. Since it selects all rows without filtering, the output will have the same 100 rows as the source.
Final Answer:
The model will return 100 rows identical to the source table -> Option A
Quick Check:
Select * from source = same rows [OK]
Hint: Select * from source returns all rows unchanged [OK]
Common Mistakes:
Thinking it returns zero rows
Assuming aggregation happens automatically
Expecting syntax errors from correct source() usage
4. You wrote this dbt model for source table products:
select * from source('inventory', 'products')
But dbt throws an error. What is the problem?
medium
A. Model file name does not match source table
B. Wrong source table name
C. Missing double curly braces around the source function
D. Using select * is not allowed
Solution
Step 1: Check dbt source function syntax and identify issue
The source function must be wrapped in double curly braces: {{ source(...) }}. The model uses source(...) without {{ }}, causing a syntax error.
Final Answer:
Missing double curly braces around the source function -> Option C
Quick Check:
dbt functions need {{ }} [OK]
Hint: Always wrap dbt functions in {{ }} [OK]
Common Mistakes:
Forgetting {{ }} around source()
Assuming select * is disallowed
Ignoring model file naming conventions
5. You have two source tables: customers and orders. According to the one model per source table rule, how should you organize your dbt models if you want to create a report showing total orders per customer?
hard
A. Create separate base models for customers and orders, then create a third model joining them for the report
B. Create one model combining both source tables directly without base models
C. Create a single model selecting from both source tables with UNION
D. Create only one model for orders and ignore customers
Solution
Step 1: Follow one model per source table for base models and build report model
Create one model for customers and one for orders separately to keep base models simple. Create a third model that joins these base models to calculate total orders per customer, keeping transformations clear and modular.
Final Answer:
Create separate base models for customers and orders, then create a third model joining them for the report -> Option A
Quick Check:
Base models per source + separate report model [OK]
Hint: Base models per source, then join in separate model [OK]
Common Mistakes:
Combining sources in one base model
Skipping base models and joining sources directly
Ignoring one source table
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.