11-01-03 — Medallion Architecture (Bronze/Silver/Gold)

⏱ 12 minFontes validadas em: 2026-04-29

TL;DR

Medallion Architecture é o padrão de organização de dados em camadas: Bronze (dados brutos, como vieram da fonte), Silver (dados limpos e conformes, join entre fontes) e Gold (dados agregados prontos para consumo de negócio e IA). É o padrão recomendado pela Microsoft e Databricks para qualquer data lakehouse. No Fabric, cada camada vive no OneLake — a diferença é a transformação aplicada.

Por que usar Medallion

Sem arquitetura em camadas, dados de múltiplas fontes viram um "pântano de dados" — impossível de rastrear a origem de uma métrica. A Medallion resolve com rastreabilidade completa: qualquer número no dashboard Gold tem linhagem até o dado bruto no Bronze.

flowchart LR subgraph Sources SAP[SAP] SQL[SQL Server] API[APIs REST] SP[SharePoint] end subgraph Bronze — Raw B1[vendas_sap_raw] B2[clientes_sql_raw] B3[pedidos_api_raw] end subgraph Silver — Cleaned S1[vendas_conformadas] S2[clientes_deduplicados] S3[pedidos_enriquecidos] end subgraph Gold — Business G1[kpi_vendas_mensal] G2[dim_cliente] G3[fato_receita] end SAP --> B1 SQL --> B2 API --> B3 SP --> B3 B1 --> S1 B2 --> S2 B3 --> S3 S1 & S2 & S3 --> G1 & G2 & G3 G1 & G2 & G3 --> PBI[Power BI] G1 & G2 & G3 --> DA[Data Agents IA]

Camada Bronze — Raw

Bronze armazena dados exatamente como vieram da fonte. Nenhuma transformação. O objetivo é ter um backup imutável do estado original dos dados.

Regra de ouro do Bronze: Nunca delete dados do Bronze. Se a transformação da Silver errar, você pode reprocessar do Bronze sem ir à fonte novamente. É seu "undo" infinito de dados.
# Pipeline Bronze — ingestão de SAP sem transformação
from pyspark.sql.types import StringType, StructType, StructField

# Lê do SAP via JDBC (on-premises data gateway)
df_sap = spark.read \
    .format("jdbc") \
    .option("url", "jdbc:sap://sap-server:30015/") \
    .option("dbtable", "VBAK") \
    .option("user", dbutils.secrets.get("sap", "user")) \
    .option("password", dbutils.secrets.get("sap", "password")) \
    .load()

# Adiciona metadados de ingestão
from pyspark.sql.functions import current_timestamp, lit
df_bronze = df_sap \
    .withColumn("_ingest_timestamp", current_timestamp()) \
    .withColumn("_source_system", lit("SAP_ECC"))

# Salva como Delta no Bronze — append mode (imutável)
df_bronze.write.format("delta") \
    .mode("append") \
    .partitionBy("VKORG", "AUDAT") \
    .save("abfss://bronze@onelake.dfs.fabric.microsoft.com/vendas_sap/")

Camada Silver — Cleaned & Conformed

Silver aplica: limpeza (remove duplicatas, trata nulos), conformidade (padroniza formatos, converte moedas, normaliza códigos) e integração (join entre tabelas da mesma fonte ou de fontes diferentes).

# Pipeline Silver — limpeza e conformação de vendas SAP
df_bronze = spark.read.format("delta") \
    .load("abfss://bronze@onelake.dfs.fabric.microsoft.com/vendas_sap/")

from pyspark.sql.functions import col, upper, when, to_date

df_silver = df_bronze \
    .dropDuplicates(["VBELN"]) \
    .filter(col("AUDAT").isNotNull()) \
    .withColumn("data_pedido", to_date(col("AUDAT"), "yyyyMMdd")) \
    .withColumn("status_normalizado", 
        when(col("GBSTK") == "C", "Completo")
        .when(col("GBSTK") == "A", "Aberto")
        .otherwise("Desconhecido")) \
    .withColumn("valor_brl", col("NETWR") * col("taxa_cambio"))

df_silver.write.format("delta").mode("overwrite") \
    .option("mergeSchema", "true") \
    .save("abfss://silver@onelake.dfs.fabric.microsoft.com/vendas_conformadas/")

Camada Gold — Business-Ready

Gold contém dados agregados, prontos para consumo por Power BI, Data Agents e APIs. É aqui que vivem as tabelas dimensionais (dim_cliente, dim_produto) e fatos (fato_receita, fato_vendas).

# Pipeline Gold — star schema para analytics
df_silver_vendas = spark.read.format("delta") \
    .load("abfss://silver@onelake.dfs.fabric.microsoft.com/vendas_conformadas/")
df_silver_clientes = spark.read.format("delta") \
    .load("abfss://silver@onelake.dfs.fabric.microsoft.com/clientes_deduplicados/")

# Fact table
df_fato = df_silver_vendas \
    .join(df_silver_clientes, "cliente_id", "left") \
    .groupBy("data_pedido", "regiao", "produto_categoria") \
    .agg(
        {"valor_brl": "sum", "quantidade": "sum", "pedido_id": "count"}
    ) \
    .withColumnRenamed("sum(valor_brl)", "receita_total") \
    .withColumnRenamed("count(pedido_id)", "qtd_pedidos")

# Salva no Warehouse Gold via SQL (melhor performance para BI)
df_fato.write \
    .format("com.microsoft.fabric.datawarehouse") \
    .option("server", "xyz.datawarehouse.fabric.microsoft.com") \
    .option("database", "vendas_dw") \
    .mode("overwrite") \
    .save("gold.fato_receita")

Organização no Fabric

CamadaItem FabricQuem consomeRetenção típica
BronzeLakehouse (Files + Tables)Pipelines Silver, auditoria7 anos (compliance)
SilverLakehouse (Tables Delta)Pipelines Gold, Data Science2 anos
GoldWarehouse (T-SQL)Power BI, Data Agents, APIs5 anos
Anti-pattern: Nunca deixe o Power BI ou Data Agents consultando diretamente o Bronze. Dados brutos têm duplicatas, nulos e formatos inconsistentes — suas métricas serão erradas. Sempre passe pelo Silver/Gold.

Como isso se conecta

  • 11-02-01 — Data Factory orquestra os pipelines Bronze → Silver → Gold
  • 11-03-02 — Data Agents consultam tabelas Gold (dados limpos e semânticos)
  • 11-04-02 — O desafio final implementa esse pipeline completo com dados SAP

Fontes

  1. Microsoft Learn — Medallion lakehouse architecture in Fabric
  2. Databricks — Medallion Architecture (origem do conceito)
  3. Azure Databricks — Medallion architecture best practices