Introdução ao dbt: transformação de dados como se fosse código de produto
1. O que é dbt e por que ele revolucionou a engenharia de dados
1.1. Definição e origem do dbt no ecossistema moderno de dados
O dbt (data build tool) é um framework open-source que permite transformar dados dentro do data warehouse utilizando SQL como linguagem principal, mas com práticas de engenharia de software — versionamento, testes, documentação e CI/CD. Criado por Tristan Handy em 2016 e mantido pela dbt Labs, o dbt nasceu da necessidade de tratar transformações de dados com o mesmo rigor que o código de produto.
Antes do dbt, as transformações SQL eram scripts soltos, sem controle de versão adequado, sem testes automatizados e com dependências implícitas entre tabelas. O dbt resolve isso ao estruturar cada transformação como um "model" — um arquivo SQL que pode ser testado, documentado e versionado.
1.2. Paradigma "analytics engineering"
O dbt popularizou o conceito de analytics engineering — uma disciplina que fica entre a engenharia de dados e a análise de negócios. Nesse paradigma, a carga dos dados (Extract e Load) é feita por ferramentas como Fivetran, Airbyte ou Stitch, e a transformação (Transform) fica a cargo do dbt. Essa separação EL + T permite que times de dados foquem em lógica de negócio em vez de infraestrutura.
1.3. Comparação com abordagens tradicionais
Abordagem tradicional (scripts SQL soltos):
-- script_vendas_final_v3.sql
-- Cuidado: não executar antes da meia-noite!
DROP TABLE IF EXISTS vendas_agregadas;
CREATE TABLE vendas_agregadas AS
SELECT
data,
SUM(valor) as total_vendas
FROM vendas_brutas
WHERE status = 'confirmado';
-- João: adicionar filtro de data depois
Abordagem com dbt:
-- models/vendas_agregadas.sql
{{ config(materialized='table') }}
SELECT
data,
SUM(valor) as total_vendas
FROM {{ ref('vendas_brutas') }}
WHERE status = 'confirmado'
A diferença é clara: no dbt, usamos {{ ref() }} para declarar dependências, o que permite lineage automática, testes e materialização controlada.
2. Conceitos fundamentais do dbt
2.1. Models
Models são arquivos .sql que contêm uma única instrução SELECT. Cada model se torna uma view ou tabela no warehouse. Exemplo:
-- models/dim_clientes.sql
SELECT
cliente_id,
nome,
email,
data_cadastro,
CASE
WHEN total_compras > 1000 THEN 'VIP'
ELSE 'Regular'
END as categoria
FROM {{ source('ecommerce', 'clientes') }}
2.2. Sources e Seeds
- Sources: definem tabelas de origem externa (sistemas OLTP, APIs). São declaradas em YAML e permitem testes de freshness.
- Seeds: arquivos CSV que podem ser carregados como tabelas no warehouse, úteis para dados de referência pequenos.
-- schema.yml
sources:
- name: ecommerce
tables:
- name: clientes
freshness:
warn_after: {count: 12, period: hour}
2.3. Tests, Snapshots e Exposures
- Tests: verificações de qualidade (unique, not_null, accepted_values, customizados).
- Snapshots: capturam mudanças em tabelas tipo Type-2 SCD (Slowly Changing Dimensions).
- Exposures: documentam como os dados são usados downstream (dashboards, relatórios).
3. Estrutura de um projeto dbt: código de produto aplicado a dados
3.1. Organização de pastas
meu_projeto_dbt/
├── models/
│ ├── staging/
│ ├── marts/
│ └── intermediate/
├── tests/
├── snapshots/
├── macros/
├── seeds/
├── dbt_project.yml
└── packages.yml
O arquivo dbt_project.yml configura o projeto:
name: 'meu_projeto'
version: '1.0.0'
profile: 'snowflake'
models:
meu_projeto:
staging:
+materialized: view
+schema: staging
marts:
+materialized: table
+schema: analytics
3.2. Materializações
- view: cria uma view no warehouse (padrão).
- table: recria a tabela a cada execução.
- incremental: adiciona apenas novos registros.
- ephemeral: modelo temporário usado apenas como CTE.
3.3. Documentação e lineage
O dbt gera automaticamente um site de documentação com o comando dbt docs generate. Esse site mostra:
- Diagrama de lineage interativo (árvore de dependências)
- Descrições de colunas e modelos
- Resultados de testes
4. Ciclo de vida de desenvolvimento com dbt
4.1. Comandos principais
# Desenvolvimento local
dbt run -- Executa todos os models
dbt build -- Executa models + testes + snapshots
dbt compile -- Gera SQL compilado (sem executar)
dbt run --select dim_clientes+ -- Executa modelo e seus dependentes
4.2. Testes e validação
-- tests/generic/positive_value.sql
{% test positive_value(model, column_name) %}
SELECT *
FROM {{ model }}
WHERE {{ column_name }} < 0
{% endtest %}
-- schema.yml
models:
- name: fat_vendas
columns:
- name: valor_total
tests:
- positive_value
4.3. Versionamento e CI/CD
O dbt se integra nativamente com Git. Uma pipeline típica de CI/CD:
# .github/workflows/dbt_ci.yml
jobs:
dbt_ci:
steps:
- uses: actions/checkout@v3
- run: dbt deps
- run: dbt build --select state:modified+ --defer
5. Padrões avançados e boas práticas
5.1. Macros e Jinja
Macros permitem reutilizar lógica SQL:
-- macros/clean_string.sql
{% macro clean_string(column_name) %}
TRIM(REGEXP_REPLACE({{ column_name }}, '[^a-zA-Z0-9 ]', ''))
{% endmacro %}
-- Uso no model:
SELECT {{ clean_string('nome_cliente') }} as nome_limpo
FROM clientes
5.2. Estratégias de transformação incremental
Para grandes volumes, use modelos incrementais:
{{ config(
materialized='incremental',
unique_key='order_id',
incremental_strategy='merge'
) }}
SELECT *
FROM {{ ref('stg_orders') }}
{% if is_incremental() %}
WHERE updated_at > (SELECT MAX(updated_at) FROM {{ this }})
{% endif %}
5.3. Hooks e operadores
Hooks executam comandos antes/depois das transformações:
-- dbt_project.yml
on_run_start:
- "GRANT USAGE ON SCHEMA {{ target.schema }} TO ROLE ANALYTICS"
on_run_end:
- "{{ log('Execução concluída!', info=True) }}"
6. Integração com o ecossistema de dados moderno
6.1. Conectando a data warehouses
O dbt suporta nativamente:
- Snowflake (via conexão nativa ou Snowpark)
- BigQuery (via service account)
- Redshift (via psycopg2)
- Databricks (via Spark SQL ou Delta Lake)
- PostgreSQL, DuckDB e outros
6.2. dbt + orquestradores
# Exemplo de DAG no Airflow
with DAG('dbt_pipeline', schedule='@daily') as dag:
dbt_run = BashOperator(
task_id='dbt_run',
bash_command='dbt run --models marts+'
)
dbt_test = BashOperator(
task_id='dbt_test',
bash_command='dbt test --select marts+'
)
dbt_run >> dbt_test
6.3. dbt Cloud vs. dbt Core
| Característica | dbt Core | dbt Cloud |
|---|---|---|
| Custo | Gratuito | Pago (SaaS) |
| Interface | Linha de comando | Web IDE |
| CI/CD | Manual | Integrado |
| Gerenciamento | Você gerencia | Gerenciado |
7. Casos de uso práticos e resultados mensuráveis
7.1. Exemplo completo: pipeline de vendas
-- models/staging/stg_orders.sql
SELECT
order_id,
customer_id,
order_date,
total_amount,
status
FROM {{ source('raw', 'orders') }}
WHERE order_date >= '2020-01-01'
-- models/marts/dim_customers.sql
SELECT
customer_id,
customer_name,
city,
segment
FROM {{ ref('stg_customers') }}
-- models/marts/fct_orders.sql
SELECT
o.order_id,
o.customer_id,
o.order_date,
o.total_amount,
c.customer_name,
c.city
FROM {{ ref('stg_orders') }} o
JOIN {{ ref('dim_customers') }} c
ON o.customer_id = c.customer_id
7.2. Redução de tempo de entrega
Antes do dbt: adicionar nova fonte de dados levava 2-3 semanas (scripts manuais, testes manuais, documentação separada). Com dbt: 2-3 dias (model + teste + documentação automática).
7.3. Métricas de sucesso
- 100% de testes passando em cada deploy
- Documentação viva atualizada automaticamente
- Tempo de onboarding de novos analistas reduzido de semanas para dias
- Confiança do time nos dados (testes de qualidade rodam a cada execução)
O dbt transformou a engenharia de dados ao aplicar princípios de desenvolvimento de software — modularidade, testabilidade, versionamento e documentação — ao mundo das transformações SQL. Se você ainda não experimentou, comece com dbt init e veja como seus dados podem ser tratados como código de produto.
Referências
- Documentação oficial do dbt — Guia completo de instalação, conceitos e referência de comandos.
- dbt Learn - Curso gratuito "Fundamentals" — Curso interativo oficial para iniciantes, com exercícios práticos.
- Analytics Engineering: A Guide to dbt — Artigo técnico detalhando o papel do analytics engineer e como o dbt se encaixa.
- dbt Best Practices Guide — Documentação oficial com padrões de nomenclatura, organização de projetos e modelagem.
- dbt + Airflow: Orchestrating dbt Runs — Tutorial da Astronomer sobre integração de dbt com Airflow para pipelines complexos.
- dbt Core vs dbt Cloud: Which One Should You Use? — Artigo comparativo no Towards Data Science com cenários de escolha.