dbt

Junior

Como configuro o sources.yml do dbt para que dados obsoletos falhem alto, não em silêncio?

Um model pode rodar limpo contra uma tabela que parou de atualizar há três dias. O sources.yml é onde você diz ao dbt para realmente checar isso, em vez de confiar que o upstream está bem.

Ler em:
Nenhuma fonte declarada Declarada, sem freshness Freshness nunca rodado
Como a cobertura de fontes da maioria dos times costuma ficar na prática, aproximadamente nessa ordem - não um levantamento medido.

Models do dbt podem ler de qualquer tabela sem declará-la como fonte - mas só uma fonte declarada ganha rastreamento de linhagem, documentação e checagens de freshness. Sem isso, uma carga upstream parada simplesmente parece um run bem-sucedido normal.

Declarando uma fonte antes de poder checar seu freshness

Uma fonte é uma declaração YAML apontando para uma tabela que o dbt não construiu - tipicamente dados brutos entregues por Fivetran, Airbyte, ou um loader próprio. Declará-la não muda nada em como seus models a consultam; uma fonte declarada só dá ao dbt algo para anexar documentação, testes e config de freshness.

# models/staging/sources.yml sources: - name: raw_orders database: analytics schema: raw tables: - name: orders loaded_at_field: _fivetran_synced freshness: warn_after: {count: 6, period: hour} error_after: {count: 24, period: hour}

loaded_at_field é a coluna cujo valor máximo o dbt checa - quase sempre um timestamp de sincronização fornecido pelo loader, não uma coluna de data de negócio (a data do pedido e "quando essa linha chegou" são coisas diferentes, e freshness se importa com a segunda).

warn_after vs error_after, e realmente rodando a checagem

warn_after e error_after são limites independentes, não uma escalada em duas etapas do mesmo número - você pode configurar um limite warn e nenhum limite error se só quiser visibilidade. Nada disso roda como parte de um dbt run ou dbt build normal, porém - freshness é um comando próprio:

# checa toda fonte com um bloco de freshness, escreve sources.json dbt source freshness

Isso precisa ser agendado explicitamente - um passo de cron, uma tarefa separada no Airflow, o que quer que rode antes dos models que dependem dessa fonte. Um bloco de freshness configurado mas nunca invocado não pega nada; não é uma restrição passiva que o dbt aplica sozinho.

Onde isso ainda deixa uma lacuna

Freshness só diz que a tabela recebeu alguma linha recentemente - não diz nada sobre se os valores dessa linha fazem sentido, ou se a carga só escreveu metade dos registros esperados. Uma fonte pode passar no freshness e ainda assim estar errada. E o dbt source freshness sair com código diferente de zero não impede models downstream de rodar a menos que seu orquestrador esteja explicitamente configurado para checar esse código de saída e parar - o próprio dbt não faz isso por você.

Algo que o opti-pipe não checa: freshness e configuração de fontes vivem inteiramente no sources.yml, que o motor de regras nunca lê - ele só olha o que o run_results.json reporta sobre tempo de execução e status depois que um run já aconteceu.

Veja como isso fica no seu próprio pipeline.

Envie um event log real do Spark, um run_results.json do dbt ou uma exportação de métricas do Flink e receba recomendações concretas, para aprovar antes de aplicar - não mais uma regra geral.