Claude for Data Engineering: dbt, Airflow & SQL Pipelines Guide (2026)
Learn how to use Claude and Claude Code to build dbt models, write Airflow DAGs, debug SQL pipelines, and document data warehouses faster. Step-by-step tutorial with code.
Data engineers spend a disproportionate amount of their week on work that isn't actually engineering: writing boilerplate dbt YAML, tracing a broken DAG back through six upstream tasks, or reverse-engineering what a SQL model does because the person who wrote it left the company. None of that is hard in the intellectual sense — it's just slow, and it's exactly the kind of work a coding-capable AI model is good at compressing.
Claude — and specifically Claude Code, Anthropic's terminal-based coding agent — has quietly become a common tool in data engineering workflows for one reason: it can read an entire dbt project or Airflow repo, understand the dependency graph, and make changes across multiple files without you copy-pasting schema definitions into a chat window. This guide walks through concrete ways to use Claude for dbt model development, Airflow DAG authoring, and SQL pipeline debugging, with real prompts and code you can adapt today.
Why Claude Fits the Data Engineering Workflow
Most AI coding assistants were built with application code in mind — React components, REST endpoints, unit tests. Data engineering is a different shape of problem: you're usually working with long SQL files, YAML configuration, DAG definitions with implicit ordering, and schemas that live in a data warehouse rather than in the code itself. Three things make Claude a good match for that shape:
models/ directory, a full schema.yml, and several DAG files at once, instead of feeding it one query at a time and losing the cross-file context that actually causes most pipeline bugs.dbt compile, inspect the resulting SQL, and edit multiple .sql and .yml files in one pass, the same way a human engineer would when refactoring a mart layer.ref() and source() functions and Airflow's task dependencies are graph structures. Claude is reliably good at tracing "if I change this staging model, what breaks downstream" because that kind of multi-hop reasoning is exactly what modern LLMs are trained to do well.None of this replaces understanding your data model. It replaces the mechanical translation between "I know what I want this pipeline to do" and "I have working SQL and YAML that does it."
Setting Up Claude Code in a dbt Project
If you're using Claude Code (available via npm install -g @anthropic-ai/claude-code or the desktop app), point it at your dbt project root. The first thing worth doing is asking it to build context before making changes:
bashcd my-dbt-project
claudeThen, inside the session:
Read through dbt_project.yml, models/staging, and models/marts.
Summarize the layering convention this project uses (staging → intermediate → marts)
and the naming pattern for models and sources before we make any changes.This matters more than it sounds like it should. Every dbt project has slightly different conventions — some teams prefix intermediate models with int_, others don't use an intermediate layer at all. Having Claude confirm the pattern before generating new models prevents it from inventing a convention that doesn't match the rest of your repo.
Step-by-Step: Building a dbt Model with Claude
Say you need a new mart model that aggregates order data by customer cohort. Here's a realistic workflow.
Step 1 — Describe the business logic, not the SQL.Create a new mart model `models/marts/finance/fct_customer_ltv.sql` that:
- Joins stg_orders to stg_customers
- Groups by customer_id and first_order_month (cohort)
- Calculates total_revenue, order_count, and avg_order_value
- Uses ref() for all upstream models, follows the existing style in
models/marts/finance/fct_order_summary.sql
Add the corresponding schema.yml entry with column descriptions and
not_null / unique tests on customer_id.schema.yml block in the same prompt keeps the two in sync — Claude Code will typically produce something like:
sql-- models/marts/finance/fct_customer_ltv.sql
with orders as (
select * from {{ ref('stg_orders') }}
),
customers as (
select * from {{ ref('stg_customers') }}
),
joined as (
select
c.customer_id,
date_trunc('month', min(o.order_date)) over (
partition by c.customer_id
) as first_order_month,
o.order_id,
o.order_total
from orders o
inner join customers c on o.customer_id = c.customer_id
)
select
customer_id,
first_order_month,
count(distinct order_id) as order_count,
sum(order_total) as total_revenue,
round(sum(order_total) / count(distinct order_id), 2) as avg_order_value
from joined
group by 1, 2yaml# models/marts/finance/schema.yml (excerpt)
- name: fct_customer_ltv
description: "Customer lifetime value aggregated by acquisition cohort month."
columns:
- name: customer_id
description: "Unique customer identifier."
tests:
- not_null
- unique
- name: first_order_month
description: "Month of the customer's first order, used as cohort key."
- name: total_revenue
description: "Sum of order_total across all orders for the customer."dbt run --select fct_customer_ltv and dbt test --select fct_customer_ltv directly (Claude Code can execute shell commands with your permission), then paste back any compile or test errors. This closes the loop without you manually running commands and re-pasting output — Claude sees the actual error and fixes the specific line that caused it.
Writing and Debugging Airflow DAGs
Airflow pipelines fail in ways that are often obvious once you see them and tedious to trace when you don't: a task waiting on a sensor that will never fire, a schedule_interval mismatch, an XCom that silently returned None. Claude is particularly useful here because DAG debugging is mostly about reading control flow across a file, which is a strength of long-context models.
A useful debugging prompt when a DAG is stuck or failing:
Here is my DAG file and the last 200 lines of the scheduler log for run
2026-08-23. The task `transform_daily_sales` is stuck in `up_for_retry`.
Trace the dependency chain, identify the most likely cause, and suggest
a fix. Don't guess — point to the specific log line and DAG line that
support your conclusion.For new DAGs, describe the pipeline in plain terms and let Claude produce the TaskFlow API structure:
pythonfrom airflow.decorators import dag, task
from datetime import datetime, timedelta
default_args = {
"owner": "data-eng",
"retries": 2,
"retry_delay": timedelta(minutes=5),
}
@dag(
dag_id="daily_sales_pipeline",
schedule="0 6 * * *",
start_date=datetime(2026, 1, 1),
catchup=False,
default_args=default_args,
tags=["sales", "daily"],
)
def daily_sales_pipeline():
@task
def extract_raw_sales():
# pull from source system
...
@task
def load_to_warehouse(records):
# load into staging schema
...
@task
def trigger_dbt_run():
# run dbt build --select tag:daily_sales
...
records = extract_raw_sales()
load_to_warehouse(records) >> trigger_dbt_run()
daily_sales_pipeline()The value isn't that Claude "knows" the TaskFlow API better than you do — it's that it can hold your existing DAG conventions (retry policy, tagging, naming) in context and apply them consistently across every new DAG you ask it to write, which is where human-written pipelines tend to drift.
Generating Warehouse Documentation
Undocumented data warehouses are the norm, not the exception — most teams write model descriptions once during initial development and then never update them as logic changes. Claude is well suited to closing that gap because documentation generation is fundamentally a summarization task over code it can already read in full.
A practical pattern: point Claude Code at a directory of undocumented models and ask it to draft descriptions grounded in the actual SQL, not generic placeholders.
Go through every .sql file in models/marts/finance that has no matching
description in schema.yml. For each one, read the SQL logic and write a
one-sentence model description plus column-level descriptions for any
column whose name isn't self-explanatory (skip ones like customer_id).
Output as a schema.yml patch, don't rewrite the whole file.Asking for a "patch" rather than a full rewrite matters in practice — it keeps existing hand-written descriptions intact and makes the diff reviewable, rather than silently overwriting documentation someone already spent time getting right. The same approach works for generating a data dictionary from information_schema output, or writing README-style architecture docs that explain why a mart layer is structured the way it is — useful onboarding material that most teams never get around to writing themselves.
Claude vs. Other AI Tools for Data Engineering
| Task | Claude / Claude Code | Generic Copilot-style autocomplete | Plain SQL/dbt docs |
|---|---|---|---|
| Multi-file dbt refactor (staging → marts) | Strong — reads full project, edits multiple files coherently | Weak — suggests one file at a time, no cross-file awareness | N/A |
| Tracing a broken DAG across tasks/logs | Strong — reasons over dependency graph + logs together | Weak — no log ingestion | N/A |
| Generating schema tests alongside models | Strong when prompted explicitly | Inconsistent — often omits tests | N/A |
| Explaining legacy SQL you didn't write | Strong — can annotate line-by-line | Moderate | Requires you to reverse-engineer manually |
| Warehouse cost/query optimization suggestions | Good with query plan pasted in | Weak | Requires domain expertise |
The pattern across all five rows: Claude's advantage compounds when the task spans multiple files or requires reasoning over both code and runtime output (logs, query plans, test failures) at once. For single-line autocomplete, any modern assistant is roughly equivalent.
Common Mistakes to Avoid
- Not giving Claude the schema. If Claude doesn't know your warehouse's actual column names and types, it will guess plausible-sounding ones. Paste
dbt docs generateoutput, aninformation_schemaquery result, or yourschema.ymlbefore asking for new models. - Skipping the test-writing step. It's tempting to accept a generated model and move on. Always ask for the matching
not_null,unique, andrelationshipstests in the same request — untested models are where silent data quality bugs live. - Letting it invent a new layering convention. dbt projects only stay maintainable if every model follows the same staging/intermediate/marts pattern. Anchor every prompt to an existing model as a style reference.
- Trusting DAG fixes without checking the scheduler logs yourself. Claude's diagnosis is usually right, but Airflow failures sometimes have infrastructure causes (worker OOM, connection pool exhaustion) that aren't visible in the DAG file alone — verify against the actual log timestamps.
Key Takeaways
- Claude and Claude Code are strongest on data engineering tasks that span multiple files: dbt refactors, DAG dependency tracing, and warehouse documentation.
- Always provide real schema information (via
dbt docs,information_schema, orschema.yml) — without it, Claude will generate plausible but incorrect column names. - Pair every generated dbt model with its schema tests in the same prompt; don't treat testing as a separate step.
- For Airflow debugging, give Claude both the DAG file and the actual scheduler logs — diagnosis without logs is guesswork, even for a strong model.
Next Steps
If you're building toward a career in AI-augmented data engineering — or just want a structured way to validate what you know about using Claude in production workflows — the Claude Certified Architect (CCA) practice tests on AI for Anything cover agentic tool use, context management, and API integration patterns that show up directly in workflows like the ones above. Start with a free sample quiz to see where your gaps are before you sit the real exam.
Rohit Mote
Founder, AI for Anything
Rohit Mote is the founder of AI for Anything and builds AI-powered products full-time across the Infinite Products Machine portfolio. Every guide is grounded in hands-on daily use of Claude, Claude Code, and the broader AI tool ecosystem in production systems.
How we create and review our guides →