Pipeline de dados de ponta a ponta simulando um e-commerce brasileiro, usando a stack moderna de engenharia de dados.
┌──────────────────┐ ┌──────────────────────────────────────────────────────────────────┐
│ Source Postgres │ │ Data Warehouse (Postgres) │
│ (Operacional) │ │ │
│ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ clientes │ │ │ LANDING │ │ RAW │ │ SILVER │ │ GOLD │ │
│ produtos │────►│ │(extract) │─►│(dbt view)│─►│(dbt tbl) │─►│(dbt tbl) │ │
│ pedidos │ │ │ │ │ │ │ │ │ │ │
│ itens_pedido │ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
│ categorias │ │ dados brutos tradução PT limpeza e dims, facts │
└──────────────────┘ │ + metadados → EN + cast enriquec. e marts │
└──────────────────────────────────────────────────────────────────┘
▲
┌──────────┴──────────┐
│ Apache Airflow │
│ (orquestra diário) │
└─────────────────────┘
| Componente | Tecnologia | Porta |
|---|---|---|
| Banco Operacional | PostgreSQL 16 | 5432 |
| Data Warehouse | PostgreSQL 16 | 5432 |
| Extração (EL) | Python / Airbyte-style | — |
| Transformação | dbt-core 1.11.8 + dbt-postgres | — |
| Orquestração | Apache Airflow 2.9 | 8080 |
| Documentação dbt | dbt docs serve | 8081 |
Dados brutos exatamente como vieram do operacional, com colunas de metadados estilo Airbyte:
_airbyte_raw_id— UUID único por registro_airbyte_extracted_at— timestamp da extração_airbyte_loaded_at— timestamp do carregamento
Views sobre o landing que traduzem nomes de colunas do português para inglês e fazem cast explícito de tipos. Sem lógica de negócio.
Dados limpos e padronizados:
stg_customers— nome em title case, email em lowercase, telefone normalizado, região derivada do estadostg_products— enriquecido com categoria, faixas de preço e status de estoquestg_orders— status agrupado, colunas de data derivadas, tempo de processamentostg_order_items— total do item calculado, filtros de qualidade
Modelos analíticos prontos para consumo por BI / APIs:
| Modelo | Descrição |
|---|---|
dim_customers |
Dimensão cliente com segmentação RFM e histórico de compras |
dim_products |
Dimensão produto com métricas de vendas e popularidade |
fct_orders |
Fato pedidos (tabela central do modelo dimensional) |
mart_daily_sales |
Vendas diárias com acumulados mensais e taxas |
mart_customer_ltv |
LTV, scores RFM (1-5) e segmentação por cliente |
mart_product_performance |
Receita, ranking e curva ABC por produto |
- Docker Desktop (ou Docker Engine + Compose)
- 4 GB de RAM disponível para os containers
git clone https://github.com/<seu-usuario>/modern-data-stack.git
cd modern-data-stackcp .env.example .envO
.env.examplejá vem com os valores padrão para desenvolvimento local. Você só precisa gerar aAIRFLOW__CORE__FERNET_KEY:python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
make up
# ou:
docker compose up -d --buildAguarde ~60 segundos para todos os serviços inicializarem.
make dbt-install# Extração: source → landing
make airbyte-extract
# Transformações dbt (camada a camada)
make dbt-run-raw
make dbt-run-silver
make dbt-run-gold
# Testes de qualidade
make dbt-testOu rode tudo de uma vez pelo Airflow:
- Acesse http://localhost:8080 (admin / admin)
- Ative a DAG
modern_data_stack_pipeline - Clique em Trigger DAG
# Banco operacional
make psql-source
# Data Warehouse
make psql-warehouseExemplo de query no warehouse:
-- Top 10 clientes por LTV
SELECT customer_name, rfm_segment, net_monetary, estimated_annual_ltv
FROM gold.mart_customer_ltv
ORDER BY net_monetary DESC
LIMIT 10;
-- Receita diária dos últimos 30 dias
SELECT order_date, gross_revenue, net_revenue, total_orders, cancellation_rate_pct
FROM gold.mart_daily_sales
WHERE order_date >= current_date - 30
ORDER BY order_date;
-- Curva ABC de produtos
SELECT abc_curve, count(*) as produtos, sum(total_net_revenue) as receita
FROM gold.mart_product_performance
GROUP BY 1 ORDER BY 1;make dbt-docs
# Acesse: http://localhost:8081A DAG modern_data_stack_pipeline roda automaticamente todo dia às 02:00 BRT.
Grafo de dependências:
check_connectivity
│
extract_to_landing
│
dbt_run_raw ──► dbt_test_raw
│
dbt_run_silver ──► dbt_test_silver
│
dbt_run_gold ──► dbt_test_gold
│
dbt_docs_generate
modern-data-stack/
├── docker-compose.yml
├── .env.example # Copie para .env antes de rodar
├── Makefile
├── postgres/
│ ├── init.sh
│ ├── source/init.sql # DDL + dados operacionais
│ └── warehouse/init.sql # Schemas landing/raw/silver/gold
├── scripts/ # Setup alternativo sem Docker
│ ├── 01_create_databases.sql
│ ├── 02_populate_source_db.sql
│ └── 03_setup_warehouse.sql
├── airbyte/
│ └── extract.py # Extração source → landing (Airbyte-style)
├── dbt/
│ ├── dbt_project.yml
│ ├── profiles.yml
│ ├── packages.yml
│ ├── macros/
│ │ └── generate_schema_name.sql
│ ├── models/
│ │ ├── sources.yml # Fonte: schema landing
│ │ ├── raw/ # Views: tradução PT→EN + cast de tipos
│ │ ├── silver/ # Tabelas: limpeza e padronização
│ │ └── gold/ # Tabelas: dims, facts e marts analíticos
│ └── tests/singular/ # Testes de negócio customizados
└── airflow/
├── Dockerfile
├── requirements.txt
└── dags/
└── modern_data_stack_dag.py
O script airbyte/extract.py replica o que o Airbyte faz internamente. Para usar o Airbyte real em produção:
- Instale o Airbyte (via Docker ou Airbyte Cloud)
- Configure uma conexão source-postgres apontando para
source_postgres - Configure um destination-postgres apontando para
warehouse_postgres, schemalanding - Substitua a task
extract_to_landingna DAG peloAirbyteTriggerSyncOperator
from airflow.providers.airbyte.operators.airbyte import AirbyteTriggerSyncOperator
extract_to_landing = AirbyteTriggerSyncOperator(
task_id="extract_to_landing",
airbyte_conn_id="airbyte_default",
connection_id="<seu-connection-id>",
asynchronous=False,
)