Dataform é a ferramenta de transformação de dados integrada nativamente ao BigQuery. Permite definir pipelines de transformação SQL com dependências, testes de qualidade e documentação, tudo versionado em Git.

Foi adquirida pelo Google em 2020 e integrada diretamente ao console do BigQuery em 2022, sem custo adicional além do processamento das queries no BigQuery.

Dataform vs dbt

Ambos resolvem o mesmo problema: organizar e testar transformações SQL no warehouse. As diferenças são principalmente de integração e ecossistema.

Dataformdbt
Integração GCPNativa (console BigQuery, IAM, GitHub)Via adapter (dbt-bigquery)
LinguagemSQLX (SQL + bloco de config JS)Jinja + SQL (.sql + .yml)
ExecuçãoNo próprio console GCP ou via APICLI local, dbt Cloud ou Airflow
CustoGratuito (paga só o BigQuery)dbt Core gratuito; dbt Cloud pago
TestesAssertions (SQL customizado)Tests genéricos + singular tests
DocumentaçãoAutomática via tags e descriçõesschema.yml com description:
WarehouseFocado em BigQueryMulti-warehouse (BQ, Snowflake, Redshift…)
ComunidadeMenor, mais recenteGrande, madura (pacotes, hub)

Quando preferir Dataform: time 100% em GCP, quer integração nativa com IAM e console, sem necessidade de manter ambiente dbt separado.

Quando preferir dbt: multi-cloud ou multi-warehouse, time já experiente com dbt, precisa de pacotes da comunidade (dbt-utils, dbt-expectations, etc.).

SQLX: a linguagem do Dataform

SQLX é SQL com um bloco de configuração JavaScript no topo. O Dataform compila SQLX em SQL puro antes de executar no BigQuery.

Tabela simples

-- definitions/trusted/pedidos_diarios.sqlx
config {
  type: "table",
  schema: "trusted",
  description: "Pedidos agregados por dia e região",
  tags: ["diario", "pedidos"],
  bigquery: {
    partitionBy: "data",
    clusterBy: ["regiao"]
  }
}
 
SELECT
  DATE(criado_em)  AS data,
  regiao,
  COUNT(*)         AS qtd_pedidos,
  SUM(valor)       AS receita
FROM ${ref("staging", "stg_pedidos")}
WHERE status != 'cancelado'
GROUP BY 1, 2

O ${ref("schema", "tabela")} é o equivalente ao {{ ref('tabela') }} do dbt: cria a dependência declarativamente e substitui pelo nome completo da tabela no BigQuery.

View

config {
  type: "view",
  schema: "marts"
}
 
SELECT * FROM ${ref("pedidos_diarios")}
WHERE data >= DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY)

Tabela incremental

Adiciona apenas os dados novos em vez de recriar a tabela inteira:

config {
  type: "incremental",
  schema: "trusted",
  bigquery: {
    partitionBy: "data_evento",
    updatePartitionFilter: "data_evento >= DATE_SUB(CURRENT_DATE(), INTERVAL 3 DAY)"
  }
}
 
SELECT
  DATE(ts)     AS data_evento,
  evento_tipo,
  usuario_id,
  COUNT(*)     AS ocorrencias
FROM ${ref("raw", "eventos")}
 
-- Filtro aplicado apenas em runs incrementais
${when(incremental(), `WHERE ts >= (SELECT MAX(ts) FROM ${self()})`)}
 
GROUP BY 1, 2, 3

Assertions (testes)

Assertions são queries SQL que retornam linhas quando há problemas. Se retornar qualquer linha, o workflow falha:

-- definitions/assertions/pedidos_sem_cliente.sqlx
config {
  type: "assertion",
  tags: ["qualidade"]
}
 
-- Falha se existir pedido sem cliente_id
SELECT * FROM ${ref("pedidos_diarios")}
WHERE cliente_id IS NULL

Dataform também tem assertions inline na config da tabela:

config {
  type: "table",
  assertions: {
    nonNull: ["pedido_id", "cliente_id", "data"],
    uniqueKey: ["pedido_id"],
    rowConditions: ["valor > 0", "status IN ('ativo', 'cancelado', 'entregue')"]
  }
}

Declarações (sources externas)

Para referenciar tabelas que não são gerenciadas pelo Dataform (ex: tabelas de ingestão):

-- definitions/sources/raw_pedidos.sqlx
config {
  type: "declaration",
  schema: "raw",
  name: "pedidos",
  description: "Pedidos brutos vindos da ingestão via Dataflow"
}

Estrutura de um projeto Dataform

dataform/
├── dataform.json          ← configuração do projeto (projeto GCP, dataset padrão)
├── definitions/
│   ├── sources/           ← declarações de tabelas externas
│   ├── staging/           ← limpeza e tipagem dos dados brutos
│   ├── trusted/           ← transformações de negócio
│   ├── marts/             ← camada de consumo (BI, APIs)
│   └── assertions/        ← testes de qualidade
├── includes/              ← macros JavaScript reutilizáveis
└── package.json

dataform.json

{
  "defaultSchema": "dataform",
  "assertionSchema": "dataform_assertions",
  "warehouse": "bigquery",
  "defaultDatabase": "meu-projeto",
  "defaultLocation": "US"
}

Macros JavaScript (includes)

Funções reutilizáveis entre arquivos SQLX:

// includes/helpers.js
function formatar_data(coluna) {
  return `FORMAT_DATE('%Y-%m', ${coluna})`;
}
 
function filtro_periodo(coluna, dias) {
  return `${coluna} >= DATE_SUB(CURRENT_DATE(), INTERVAL ${dias} DAY)`;
}
 
module.exports = { formatar_data, filtro_periodo };
-- Usar no SQLX
config { type: "view" }
 
SELECT
  ${helpers.formatar_data("data_pedido")} AS mes,
  SUM(valor) AS receita
FROM ${ref("pedidos")}
WHERE ${helpers.filtro_periodo("data_pedido", 90)}
GROUP BY 1

Execução e agendamento

Via console GCP

Workflows são executados pelo console do BigQuery em Dataform > Workspaces. É possível acionar manualmente ou configurar um schedule com frequência e fuso horário.

Via API (para integração com Cloud Composer)

from airflow.providers.google.cloud.operators.dataform import (
    DataformCreateCompilationResultOperator,
    DataformCreateWorkflowInvocationOperator,
)
 
compilar = DataformCreateCompilationResultOperator(
    task_id="compilar",
    project_id="meu-projeto",
    region="us-central1",
    repository_id="meu-repo",
)
 
executar = DataformCreateWorkflowInvocationOperator(
    task_id="executar",
    project_id="meu-projeto",
    region="us-central1",
    repository_id="meu-repo",
    compilation_result=compilar.output,
)
 
compilar >> executar

Integração com Git

Dataform se conecta nativamente a repositórios GitHub, GitLab e Cloud Source Repositories. Cada workspace é uma branch isolada. O fluxo típico:

flowchart LR
    W["Workspace - branch feature"] -->|PR| M[Branch main]
    M -->|schedule| E[Execução no BigQuery]
    E --> BQ[(BigQuery)]

Ver também: gcp-bigquery | gcp-bigquery-sql | gcp-bigquery-otimizacao | gcp-cloud-composer | gcp-dataplex