Skip to content

Data Pipeline: acelera ingestão de população IBGE com batch e autodetecção de período válido#79

Merged
rebecanonato89 merged 1 commit intomainfrom
perf/pipeline-populacao-ibge-batch-dburl-jdbc
Mar 31, 2026
Merged

Data Pipeline: acelera ingestão de população IBGE com batch e autodetecção de período válido#79
rebecanonato89 merged 1 commit intomainfrom
perf/pipeline-populacao-ibge-batch-dburl-jdbc

Conversation

@matheuscarvalheira
Copy link
Copy Markdown
Contributor

🚀 Descrição

Este PR introduz melhorias significativas de performance, robustez e compatibilidade no pipeline de ingestão de população (IBGE), eliminando gargalos críticos e reduzindo drasticamente o tempo de execução.


✅ O que foi feito

1) Otimização massiva da etapa de População (IBGE)

Problema anterior

  • O pipeline realizava consultas à API do IBGE município por município (~5.5k requests).
  • Havia uso de sleep configurável por requisição (POP_REQUEST_SLEEP_SECONDS), aumentando ainda mais o tempo total.
  • Resultado: throughput extremamente baixo (ex.: ~0.15 municípios/segundo) e tempo estimado de execução de várias horas.

Solução implementada

  • Implementação de consultas em lote utilizando a API de agregados do IBGE (SIDRA):

    /api/v3/agregados/... ?localidades=N6[<co1>,<co2>,...]
    
  • Criação da função fetch_populacao_lote(codigos_ibge) que:

    • Monta uma única requisição para múltiplos municípios
    • Aplica retry com backoff simples
    • Faz parsing do JSON e retorna um dict {co_ibge: populacao}
  • Refatoração do fluxo principal (run()):

    • Processamento por batches de municípios
    • Uma única chamada ao IBGE por lote
    • Fallback aplicado apenas para municípios não retornados
    • Persistência em batch no banco (mantendo UPDATE_BATCH_SIZE)

Configuração

  • Nova variável:

    • POP_IBGE_BATCH_SIZE (default: 100)
  • POP_REQUEST_SLEEP_SECONDS agora é aplicado entre lotes (não mais por município), reduzindo risco de rate limit sem impactar performance.

Resultado

  • Redução de execução de horas para segundos (validado em ambiente real - WSL).

2) Autodetecção de período válido do IBGE

Problema

  • A API do IBGE pode retornar vazio ([]) para determinados anos (ex.: 2022/2023), mesmo com requisições válidas.

  • Isso causava:

    • Chamadas inúteis em massa
    • Uso excessivo de fallback
    • Degradação da qualidade dos dados

Solução implementada

  • Criação da função _discover_periodo_disponivel(preferido):

    • Tenta o período preferido (ex.: 2023)
    • Caso vazio, retrocede até encontrar um período válido
    • Resultado é cacheado em _CACHED_IBGE_PERIODO_OK
  • Estratégia de descoberta baseada em probe estável:

    • Município: 3550308 (São Paulo)

Configuração

  • POP_IBGE_PERIODO (default: "2023") passa a ser apenas um valor preferencial
  • Ajuste automático para períodos válidos quando necessário

3) Normalização de DB_URL (compatibilidade JDBC)

Problema

  • O SQLAlchemy não aceita URLs no formato JDBC:

    jdbc:postgresql://...
    
  • Erro gerado:

    Could not parse SQLAlchemy URL from given URL string
    

Solução implementada

  • Implementação de _normalize_db_url(db_url) em config.py:

    • Converte automaticamente:

      jdbc:postgresql:// → postgresql://
      
  • Permite reutilizar o mesmo .env entre aplicações Java e Python sem ajustes adicionais


🗂️ Arquivos alterados

data-pipeline/ingest_populacao.py

Adições

  • fetch_populacao_lote(codigos_ibge)
  • _discover_periodo_disponivel(preferido)
  • Cache _CACHED_IBGE_PERIODO_OK

Alterações

  • Uso de POP_IBGE_PERIODO via variáveis de ambiente
  • Refatoração do run() para processamento em batches (POP_IBGE_BATCH_SIZE)

Mantido

  • Fallback por UF (POPULACAO_FALLBACK_UF)
  • Escrita em batch no banco (_flush_updates, UPDATE_BATCH_SIZE)

data-pipeline/config.py

Adições

  • _normalize_db_url(db_url)

Alterações

  • DB_URL agora é normalizado automaticamente antes do uso

🧪 Evidências de teste

  • Execução completa do run_all.py em ambiente WSL com:

    SPREADSHEET_DIR=data
    
  • Pipeline finalizou 100% com sucesso

  • Gargalo da etapa de população eliminado

Smoke test validado

  • fetch_populacao_lote retornando dados reais
  • Autodetecção de período funcionando corretamente (ex.: fallback automático para 2021 quando 2023 retorna vazio)

🎯 Impacto

  • 🚀 Performance drasticamente superior (ordens de magnitude)
  • 🔁 Redução massiva de chamadas à API do IBGE
  • 🧠 Maior inteligência na seleção de período de dados
  • 🔧 Melhor compatibilidade entre ambientes (Java ↔ Python)
  • 📉 Menor risco de rate limiting
  • 📊 Melhor qualidade e consistência dos dados carregados

@rebecanonato89 rebecanonato89 merged commit 8bf8ca4 into main Mar 31, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants