dbt: SQL-Based Data Transformation That Brings Software Engineering to Analytics
dbt (data build tool) lets analysts transform data in the warehouse using SELECT statements, with built-in testing, documentation, and dependency tracking - no more unmaintainable SQL scripts.
Mahmudul Haque Qudrati
CEO & ML Engineer
One AI engineering post, weekly
LLM benchmarks, prompt techniques, and token-cost breakdowns — not another AI news roundup.
Before dbt, data transformation meant a patchwork of SQL scripts, Python ETL jobs, stored procedures, and manually maintained documentation. No tests, no dependency graph, no version control workflow. dbt fixes this by treating SQL transformations like software.
The philosophy: transform data in the warehouse, not before it. Load raw data first (using tools like Fivetran, Airbyte, or custom scripts), then transform it with dbt inside the warehouse.
Models: SQL SELECT Statements as First-Class Objects
Every dbt model is a .sql file containing a single SELECT statement. dbt handles creating the table or view.
-- models/staging/stg_orders.sql
SELECT
id AS order_id,
user_id,
created_at,
status,
CAST(total_cents AS FLOAT) / 100 AS total_usd
FROM {{ source('raw', 'orders') }}
WHERE created_at >= '2024-01-01'
-- models/marts/revenue_by_region.sql
WITH orders AS (
SELECT * FROM {{ ref('stg_orders') }} -- dependency tracked automatically
),
users AS (
SELECT * FROM {{ ref('stg_users') }}
)
SELECT
u.region,
DATE_TRUNC('month', o.created_at) AS month,
SUM(o.total_usd) AS revenue
FROM orders o
JOIN users u ON o.user_id = u.id
GROUP BY 1, 2
The ref() function is dbt's dependency system. dbt builds a DAG from all ref() calls and runs models in the right order.
Team workspace
Ship faster with chat, meetings, and projects in one place — Zlyqor.
Built-In Testing
# models/staging/schema.yml
models:
- name: stg_orders
columns:
- name: order_id
tests:
- not_null
- unique
- name: status
tests:
- accepted_values:
values: ['pending', 'shipped', 'delivered', 'cancelled']
- name: user_id
tests:
- not_null
- relationships:
to: ref('stg_users')
field: user_id
dbt test # runs all tests, fails loudly if data quality issues found
Running dbt
dbt run # build all models
dbt run --select stg_orders # build one model
dbt run --select tag:staging # build all staging models
dbt build # run + test in one command
dbt docs generate && dbt docs serve # generate and serve documentation
Snapshots for Slowly Changing Dimensions
-- snapshots/user_status_snapshot.sql
{% snapshot user_status_snapshot %}
{{
config(
target_schema='snapshots',
unique_key='user_id',
strategy='check',
check_cols=['status', 'plan'],
)
}}
SELECT * FROM {{ source('raw', 'users') }}
{% endsnapshot %}
Snapshots track how rows change over time - essential for SCD type 2 dimensions.
dbt Cloud vs dbt Core
dbt Core (open source): CLI tool, runs anywhere, connects to your warehouse. Free forever.
dbt Cloud: Managed platform with a web IDE, scheduled runs, CI/CD, and a semantic layer. Free tier exists; paid plans for teams.
dbt vs Spark/Airflow
dbt is complementary, not a replacement. Airflow orchestrates jobs (including running dbt). Spark processes data at scale before it reaches the warehouse. dbt transforms data inside the warehouse with SQL. Most modern stacks use all three.
Mahmudul Haque Qudrati
CEO & ML Engineer
Visionary leader with extensive experience in machine learning and software development. Drives strategic innovation and business growth.
More from Mahmudul
Related Articles
Pandas for Software Developers: The Complete Guide to Data Manipulation in Python
Pandas is the dominant Python library for data manipulation. Here is what every developer needs to know to use it effectively.
Exploratory Data Analysis: The Complete EDA Checklist for Data Scientists
EDA is the process of understanding a dataset before modeling. Skip it and your models will fail in ways you cannot explain.
Data Visualization in Python: When to Use Matplotlib, Seaborn, Plotly, and Altair
The right visualization tool depends on your goal. Here is the complete hierarchy and when to use each chart type.
// discussion
Comments