From 640270aced3f3bcad83923ef44fa9a6a91aa44b4 Mon Sep 17 00:00:00 2001 From: arthrok Date: Sun, 14 Jun 2026 22:00:51 -0300 Subject: [PATCH 1/4] refactor: altera estrutura de pastas do projeto --- .github/workflows/main.yaml | 4 +- Dockerfile | 40 ------ Dockerfile.superset | 12 -- Makefile | 30 ++++- README.md | 124 +++++++----------- airflow_lappis/airflow.cfg | 6 - dags/.airflowignore | 7 + .../dags => dags}/dashboards/__init__.py | 0 .../dashboards/dashboard_servidores_dag.py | 0 .../contratos_inativos_ingest_dag.py | 0 .../compras_gov/contratos_ingest_dag.py | 0 .../compras_gov/cronograma_ingest_dag.py | 0 .../compras_gov/empenhos_ingest_dag.py | 0 .../compras_gov/faturas_ingest_dag.py | 0 .../compras_gov/terceirizados_ingest_dag.py | 0 .../dados_abertos/deputados_ingest_dag.py | 0 .../dados_abertos/senadores_ingest_dag.py | 0 .../pncp/itens_resultados_licitacoes.py | 0 .../data_ingest/pncp/licitacoes_ingest.py | 0 .../sgac/projetos_sgac_ingest_dag.py | 0 .../siafi/nota_credito_siafi_ingest_dag.py | 0 .../siafi/nota_empenho_siafi_ingest_dag.py | 0 ...programacao_financeira_siafi_ingest_dag.py | 0 ..._afastamento_historico_siape_ingest_dag.py | 0 .../dados_afastamento_siape_ingest_dag.py | 0 .../siape/dados_curriculo_siape_ingest_dag.py | 0 .../dados_dependentes_siape_ingest_dag.py | 0 .../siape/dados_escolares_siape_ingest_dag.py | 0 .../siape/dados_financeiros_siape_dag.py | 0 .../dados_funcionais_siape_ingest_dag.py | 0 .../siape/dados_pa_siape_ingest_dag.py | 0 .../siape/dados_pessoais_siape_ingest_dag.py | 0 .../siape/dados_uorg_siape_ingest_dag.py | 0 .../lista_aposentadoria_siape_ingest_dag.py | 0 .../lista_servidores_siape_ingest_dag.py | 0 .../siape/lista_uorgs_siape_ingest_dag.py | 0 .../pensoes_instituidas_siape_ingest_dag.py | 0 .../siorg/cargos_funcao_ingest_dag.py | 0 ...rutura_organizacional_cargos_ingest_dag.py | 0 .../unidade_organizacional_ingest_dag.py | 0 .../empenhos_tesouro_emendas_ingest_dag.py | 0 .../empenhos_tesouro_ingest_dag.py | 0 ..._execucao_outras_fontes_mcid_ingest_dag.py | 0 ...mpenho_emendas_parlamentares_ingest_dag.py | 0 .../orcamento_mcid_por_acao_ingest_dag.py | 0 ...penhos_tesouro_parlamentares_ingest_dag.py | 0 .../nc_tesouro_ingest.dag.py | 0 .../pf_tesouro_ingest_dag.py | 0 .../visao_orcamentaria_ingest.py | 0 .../transfere_gov/minc/api_programas_dag.py | 0 .../minc/minc_api_anexos_relatorios_dag.py | 0 .../minc/minc_api_planos_acao_dag.py | 0 .../minc/minc_api_relatorios_gestao_dag.py | 0 .../minc/minc_download_anexos_dag.py | 0 .../minc/minc_extracao_anexos_dag.py | 0 .../mir/notas_de_credito_ingest_mir_dag.py | 0 .../mir/plano_acao_ingest_mir_dag.py | 0 .../mir/programa_financeira_ingest_mir_dag.py | 0 .../mir/programas_ingest_mir_dag.py | 0 .../notas_de_credito_ingest_dag.py | 0 .../transfere_gov/plano_acao_ingest_dag.py | 0 .../programa_beneficiario_ingest_dag.py | 0 .../programacao_financeira_ingest_dag.py | 0 .../transfere_gov/programas_ingest_dag.py | 0 .../documentos_habeis_especias_ingest_dag.py | 0 .../empenhos_especiais_ingest_dag.py | 0 .../executor_especial_ingest_dag.py | 0 .../finalidade_especial_ingest_dag.py | 0 ...storico_pagamentos_especiais_ingest_dag.py | 0 .../metas_especiais_ingest_dag.py | 0 .../ordem_bancaria_especial_ingest_dag.py | 0 .../plano_trabalho_especial_ingest_dag.py | 0 .../planos_acao_especiais_ingest_dag.py | 0 .../programas_especiais_ingest_dag.py | 0 ...latorio_gestao_novo_especial_ingest_dag.py | 0 .../reltorio_gestao_ingest.py | 0 .../dbt/ipea_cosmos_dag.py | 4 +- .../dbt/mir_cosmos_dag.py | 4 +- {airflow_lappis/dags/dbt => dbt}/.user.yml | 0 .../dags/dbt => dbt}/ipea/.user.yml | 0 .../dags/dbt => dbt}/ipea/dbt_project.yml | 0 .../dags/dbt => dbt}/ipea/descriptions.yml | 0 .../dbt => dbt}/ipea/macros/create_udfs.sql | 0 .../macros/data_quality/row_count_match.sql | 0 .../data_quality/verificacao_tipagem.sql | 0 .../ipea/macros/get_custom_schema.sql | 0 .../macros/metadata/generate_metadata.sql | 0 .../ipea/macros/parse_financial_value.sql | 0 .../dags/dbt => dbt}/ipea/macros/schema.yml | 0 .../ipea/macros/udfs/f_format_nc.sql | 0 .../ipea/macros/udfs/f_parse_dates.sql | 0 .../models/contratos_dbt/bronze/contratos.sql | 0 .../contratos_dbt/bronze/cronogramas.sql | 0 .../models/contratos_dbt/bronze/empenhos.sql | 0 .../contratos_dbt/bronze/empenhos_tesouro.sql | 0 .../models/contratos_dbt/bronze/faturas.sql | 0 .../models/contratos_dbt/bronze/schema.yml | 0 .../gold/contratos_comparativo_mensal.sql | 0 .../contratos_dbt/gold/contratos_resumo.sql | 0 .../gold/contratos_somatorio.sql | 0 .../ipea/models/contratos_dbt/gold/schema.yml | 0 .../silver/contratos_empenhos.sql | 0 .../silver/contratos_estagios.sql | 0 .../silver/contratos_faturas.sql | 0 .../silver/cronogramas_faturas_mensal.sql | 0 .../contratos_dbt/silver/estagios_mensal.sql | 0 .../models/contratos_dbt/silver/schema.yml | 0 .../contratos_dbt/views/identificadores.sql | 0 .../views/preenchimento_meses.sql | 0 .../models/contratos_dbt/views/schema.yml | 0 .../ipea/models/metadata/models_metadata.sql | 0 .../ipea/models/metadata/schema.yml | 0 .../models/orcamento_dbt/bronze/schema.yml | 0 .../bronze/visao_orcamentaria_total.sql | 0 .../bronze/afastamento_historico.sql | 0 .../pessoas_dbt/bronze/cargos_funcoes.sql | 0 .../pessoas_dbt/bronze/dados_afastamento.sql | 0 .../pessoas_dbt/bronze/dados_curriculo.sql | 0 .../pessoas_dbt/bronze/dados_dependentes.sql | 0 .../pessoas_dbt/bronze/dados_escolares.sql | 0 .../pessoas_dbt/bronze/dados_financeiros.sql | 0 .../pessoas_dbt/bronze/dados_funcionais.sql | 0 .../models/pessoas_dbt/bronze/dados_pa.sql | 0 .../pessoas_dbt/bronze/dados_pessoais.sql | 0 .../models/pessoas_dbt/bronze/dados_uorg.sql | 0 .../estrutura_organizacional_cargos.sql | 0 .../pessoas_dbt/bronze/lista_servidores.sql | 0 .../models/pessoas_dbt/bronze/lista_uorgs.sql | 0 .../ipea/models/pessoas_dbt/bronze/schema.yml | 0 .../pessoas_dbt/bronze/terceirizados.sql | 0 .../bronze/unidade_organizacional.sql | 0 .../gold/aposentadorias_resumo.sql | 0 .../pessoas_dbt/gold/cargos_consolidado.sql | 0 .../pessoas_dbt/gold/distribuicao_genero.sql | 0 .../pessoas_dbt/gold/distribuicao_mapa_uf.sql | 0 .../gold/distribuicao_raca_cor.sql | 0 .../gold/distribuicao_situacao_funcional.sql | 0 .../models/pessoas_dbt/gold/hierarquia.sql | 0 .../pessoas_dbt/gold/kpis_servidores.sql | 0 .../gold/resumo_quadro_pessoal.sql | 0 .../ipea/models/pessoas_dbt/gold/schema.yml | 0 .../gold/tabela_servidores_agregada.sql | 0 .../silver/afastamento_consolidado.sql | 0 .../silver/quantitativo_alocados_ocupados.sql | 0 .../ipea/models/pessoas_dbt/silver/schema.yml | 0 .../silver/servidores_completos.sql | 0 .../silver/servidores_detalhados.sql | 0 .../silver/tabela_correlacao_cargos.sql | 0 .../unidades_organizacionais_siorg_siape.sql | 0 .../dags/dbt => dbt}/ipea/models/sources.yml | 0 .../ipea/models/ted_dbt/bronze/nc_tesouro.sql | 0 .../ipea/models/ted_dbt/bronze/pf_tesouro.sql | 0 .../models/ted_dbt/bronze/planos_acao.sql | 0 .../ipea/models/ted_dbt/bronze/schema.yml | 0 .../ipea/models/ted_dbt/gold/schema.yml | 0 .../ted_dbt/gold/ted_resumo_orcamentario.sql | 0 .../ted_dbt/silver/empenhos_plano_acao.sql | 0 .../models/ted_dbt/silver/nc_plano_acao.sql | 0 .../models/ted_dbt/silver/pf_plano_acao.sql | 0 .../ipea/models/ted_dbt/silver/schema.yml | 0 .../ted_dbt/views/num_transf_n_plano_acao.sql | 0 .../ipea/models/ted_dbt/views/schema.yml | 0 .../dags/dbt => dbt}/ipea/profiles.yml | 0 .../dbt => dbt}/ipea/seeds/estados_brasil.csv | 0 .../ipea/snapshots/tables_snapshot.yml | 0 .../dags/dbt => dbt}/mir/.user.yml | 0 .../dags/dbt => dbt}/mir/dbt_project.yml | 0 .../dags/dbt => dbt}/mir/descriptions.yml | 0 .../dbt => dbt}/mir/macros/create_udfs.sql | 0 .../macros/data_quality/row_count_match.sql | 0 .../data_quality/verificacao_tipagem.sql | 0 .../mir/macros/get_custom_schema.sql | 0 .../mir/macros/metadata/generate_metadata.sql | 0 .../mir/macros/parse_financial_value.sql | 0 .../dags/dbt => dbt}/mir/macros/schema.yml | 0 .../mir/macros/udfs/f_format_nc.sql | 0 .../mir/macros/udfs/f_parse_dates.sql | 0 .../dados_abertos_dbt/bronze/deputados.sql | 0 .../dados_abertos_dbt/bronze/schema.yml | 0 .../dados_abertos_dbt/bronze/senadores.sql | 0 .../silver/parlamentares.sql | 0 .../dados_abertos_dbt/silver/schema.yml | 0 .../emendas_dbt/bronze/documentos_habeis.sql | 0 .../emendas_dbt/bronze/empenhos_especiais.sql | 0 .../models/emendas_dbt/bronze/executor.sql | 0 .../models/emendas_dbt/bronze/finalidades.sql | 0 .../bronze/historico_pagamentos.sql | 0 .../mir/models/emendas_dbt/bronze/metas.sql | 0 .../emendas_dbt/bronze/ordens_bancarias.sql | 0 .../emendas_dbt/bronze/planos_acoes.sql | 0 .../bronze/planos_trabalho_especial.sql | 0 .../models/emendas_dbt/bronze/programas.sql | 0 .../emendas_dbt/bronze/relatorio_gestao.sql | 0 .../bronze/relatorio_gestao_novo.sql | 0 .../mir/models/emendas_dbt/bronze/schema.yml | 0 .../models/emendas_dbt/bronze/tg_emendas.sql | 0 .../emendas_dbt/silver/planos_partidos.sql | 0 .../mir/models/emendas_dbt/silver/schema.yml | 0 .../bronze/empenhos_tesouro_ted.sql | 0 .../empenhos_ted_dbt/bronze/schema.yaml | 0 .../mir/models/metadata/models_metadata.sql | 0 .../mir/models/metadata/schema.yml | 0 .../dags/dbt => dbt}/mir/models/sources.yml | 0 .../dags/dbt => dbt}/mir/profiles.yml | 0 .../dbt => dbt}/mir/seeds/partidos_logo.csv | 0 .../dbt => dbt}/mir/seeds/partidos_map.csv | 0 .../dags/dbt => dbt}/mir/seeds/schema.yml | 0 .../tests/test_parlamentares_logo_partido.sql | 0 .../dados_funcionais_handler.py | 0 .../helpers => helpers}/postgres_helpers.py | 0 .../helpers => helpers}/retry_helpers.py | 0 .../helpers => helpers}/safe_request.py | 0 infra/README.md | 33 +++++ .../docker-compose.yml | 100 ++++++-------- infra/docker/airflow-mcp/Dockerfile | 11 ++ infra/docker/airflow/Dockerfile | 64 +++++++++ {docker => infra/docker}/postgres/init.sh | 1 - infra/env/.env.example | 15 +++ .../plugins => plugins}/cliente_base.py | 0 .../plugins => plugins}/cliente_contratos.py | 0 .../plugins => plugins}/cliente_deputados.py | 0 .../plugins => plugins}/cliente_email.py | 0 .../plugins => plugins}/cliente_github.py | 0 .../plugins => plugins}/cliente_pncp.py | 0 .../plugins => plugins}/cliente_postgres.py | 0 .../plugins => plugins}/cliente_senadores.py | 0 .../plugins => plugins}/cliente_siafi.py | 0 .../plugins => plugins}/cliente_siape.py | 0 .../plugins => plugins}/cliente_siorg.py | 0 .../plugins => plugins}/cliente_ted.py | 0 .../cliente_transferegov_emendas.py | 0 .../cliente_transferegov_fundo_a_fundo.py | 0 .../plugins => plugins}/extracao_planilhas.py | 0 .../plugins => plugins}/schedule_loader.py | 0 pyproject.toml | 5 +- requirements.txt | 6 +- superset/__init__.py | 0 .../siape/consultaDadosAfastamento.xml.j2 | 0 .../consultaDadosAfastamentoHistorico.xml.j2 | 0 .../siape/consultaDadosCurriculo.xml.j2 | 0 .../siape/consultaDadosDependentes.xml.j2 | 0 .../siape/consultaDadosEscolares.xml.j2 | 0 .../siape/consultaDadosFinanceiros.xml.j2 | 0 .../siape/consultaDadosFuncionais.xml.j2 | 0 .../siape/consultaDadosPA.xml.j2 | 0 .../siape/consultaDadosPessoais.xml.j2 | 0 .../siape/consultaDadosUorg.xml.j2 | 0 .../siape/consultaPensoesInstituidas.xml.j2 | 0 .../listaInformacoesAposentadoria.xml.j2 | 0 .../siape/listaServidores.xml.j2 | 0 .../siape/listaUorgs.xml.j2 | 0 251 files changed, 257 insertions(+), 209 deletions(-) delete mode 100644 Dockerfile delete mode 100644 Dockerfile.superset delete mode 100644 airflow_lappis/airflow.cfg create mode 100644 dags/.airflowignore rename {airflow_lappis/dags => dags}/dashboards/__init__.py (100%) rename {airflow_lappis/dags => dags}/dashboards/dashboard_servidores_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/compras_gov/contratos_inativos_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/compras_gov/contratos_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/compras_gov/cronograma_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/compras_gov/empenhos_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/compras_gov/faturas_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/compras_gov/terceirizados_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/dados_abertos/deputados_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/dados_abertos/senadores_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/pncp/itens_resultados_licitacoes.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/pncp/licitacoes_ingest.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/sgac/projetos_sgac_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/siafi/nota_credito_siafi_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/siafi/nota_empenho_siafi_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/siafi/programacao_financeira_siafi_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/siape/dados_afastamento_historico_siape_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/siape/dados_afastamento_siape_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/siape/dados_curriculo_siape_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/siape/dados_dependentes_siape_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/siape/dados_escolares_siape_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/siape/dados_financeiros_siape_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/siape/dados_funcionais_siape_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/siape/dados_pa_siape_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/siape/dados_pessoais_siape_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/siape/dados_uorg_siape_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/siape/lista_aposentadoria_siape_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/siape/lista_servidores_siape_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/siape/lista_uorgs_siape_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/siape/pensoes_instituidas_siape_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/siorg/cargos_funcao_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/siorg/estrutura_organizacional_cargos_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/siorg/unidade_organizacional_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/tesouro_gerencial/empenhos_tesouro_emendas_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/tesouro_gerencial/empenhos_tesouro_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/tesouro_gerencial/mcid/dotacao_execucao_outras_fontes_mcid_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/tesouro_gerencial/mcid/empenho_emendas_parlamentares_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/tesouro_gerencial/mcid/orcamento_mcid_por_acao_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/tesouro_gerencial/mir/empenhos_tesouro_parlamentares_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/tesouro_gerencial/nc_tesouro_ingest.dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/tesouro_gerencial/pf_tesouro_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/tesouro_gerencial/visao_orcamentaria_ingest.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/transfere_gov/minc/api_programas_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/transfere_gov/minc/minc_api_anexos_relatorios_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/transfere_gov/minc/minc_api_planos_acao_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/transfere_gov/minc/minc_api_relatorios_gestao_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/transfere_gov/minc/minc_download_anexos_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/transfere_gov/minc/minc_extracao_anexos_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/transfere_gov/mir/notas_de_credito_ingest_mir_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/transfere_gov/mir/plano_acao_ingest_mir_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/transfere_gov/mir/programa_financeira_ingest_mir_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/transfere_gov/mir/programas_ingest_mir_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/transfere_gov/notas_de_credito_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/transfere_gov/plano_acao_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/transfere_gov/programa_beneficiario_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/transfere_gov/programacao_financeira_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/transfere_gov/programas_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/transferegov_emendas/documentos_habeis_especias_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/transferegov_emendas/empenhos_especiais_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/transferegov_emendas/executor_especial_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/transferegov_emendas/finalidade_especial_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/transferegov_emendas/historico_pagamentos_especiais_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/transferegov_emendas/metas_especiais_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/transferegov_emendas/ordem_bancaria_especial_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/transferegov_emendas/plano_trabalho_especial_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/transferegov_emendas/planos_acao_especiais_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/transferegov_emendas/programas_especiais_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/transferegov_emendas/relatorio_gestao_novo_especial_ingest_dag.py (100%) rename {airflow_lappis/dags => dags}/data_ingest/transferegov_emendas/reltorio_gestao_ingest.py (100%) rename airflow_lappis/dags/dbt/ipea/cosmos_dag.py => dags/dbt/ipea_cosmos_dag.py (89%) rename airflow_lappis/dags/dbt/mir/cosmos_dag.py => dags/dbt/mir_cosmos_dag.py (89%) rename {airflow_lappis/dags/dbt => dbt}/.user.yml (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/.user.yml (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/dbt_project.yml (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/descriptions.yml (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/macros/create_udfs.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/macros/data_quality/row_count_match.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/macros/data_quality/verificacao_tipagem.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/macros/get_custom_schema.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/macros/metadata/generate_metadata.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/macros/parse_financial_value.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/macros/schema.yml (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/macros/udfs/f_format_nc.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/macros/udfs/f_parse_dates.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/contratos_dbt/bronze/contratos.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/contratos_dbt/bronze/cronogramas.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/contratos_dbt/bronze/empenhos.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/contratos_dbt/bronze/empenhos_tesouro.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/contratos_dbt/bronze/faturas.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/contratos_dbt/bronze/schema.yml (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/contratos_dbt/gold/contratos_comparativo_mensal.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/contratos_dbt/gold/contratos_resumo.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/contratos_dbt/gold/contratos_somatorio.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/contratos_dbt/gold/schema.yml (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/contratos_dbt/silver/contratos_empenhos.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/contratos_dbt/silver/contratos_estagios.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/contratos_dbt/silver/contratos_faturas.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/contratos_dbt/silver/cronogramas_faturas_mensal.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/contratos_dbt/silver/estagios_mensal.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/contratos_dbt/silver/schema.yml (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/contratos_dbt/views/identificadores.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/contratos_dbt/views/preenchimento_meses.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/contratos_dbt/views/schema.yml (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/metadata/models_metadata.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/metadata/schema.yml (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/orcamento_dbt/bronze/schema.yml (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/orcamento_dbt/bronze/visao_orcamentaria_total.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/pessoas_dbt/bronze/afastamento_historico.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/pessoas_dbt/bronze/cargos_funcoes.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/pessoas_dbt/bronze/dados_afastamento.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/pessoas_dbt/bronze/dados_curriculo.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/pessoas_dbt/bronze/dados_dependentes.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/pessoas_dbt/bronze/dados_escolares.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/pessoas_dbt/bronze/dados_financeiros.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/pessoas_dbt/bronze/dados_funcionais.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/pessoas_dbt/bronze/dados_pa.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/pessoas_dbt/bronze/dados_pessoais.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/pessoas_dbt/bronze/dados_uorg.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/pessoas_dbt/bronze/estrutura_organizacional_cargos.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/pessoas_dbt/bronze/lista_servidores.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/pessoas_dbt/bronze/lista_uorgs.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/pessoas_dbt/bronze/schema.yml (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/pessoas_dbt/bronze/terceirizados.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/pessoas_dbt/bronze/unidade_organizacional.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/pessoas_dbt/gold/aposentadorias_resumo.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/pessoas_dbt/gold/cargos_consolidado.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/pessoas_dbt/gold/distribuicao_genero.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/pessoas_dbt/gold/distribuicao_mapa_uf.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/pessoas_dbt/gold/distribuicao_raca_cor.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/pessoas_dbt/gold/distribuicao_situacao_funcional.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/pessoas_dbt/gold/hierarquia.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/pessoas_dbt/gold/kpis_servidores.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/pessoas_dbt/gold/resumo_quadro_pessoal.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/pessoas_dbt/gold/schema.yml (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/pessoas_dbt/gold/tabela_servidores_agregada.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/pessoas_dbt/silver/afastamento_consolidado.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/pessoas_dbt/silver/quantitativo_alocados_ocupados.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/pessoas_dbt/silver/schema.yml (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/pessoas_dbt/silver/servidores_completos.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/pessoas_dbt/silver/servidores_detalhados.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/pessoas_dbt/silver/tabela_correlacao_cargos.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/pessoas_dbt/silver/unidades_organizacionais_siorg_siape.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/sources.yml (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/ted_dbt/bronze/nc_tesouro.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/ted_dbt/bronze/pf_tesouro.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/ted_dbt/bronze/planos_acao.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/ted_dbt/bronze/schema.yml (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/ted_dbt/gold/schema.yml (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/ted_dbt/gold/ted_resumo_orcamentario.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/ted_dbt/silver/empenhos_plano_acao.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/ted_dbt/silver/nc_plano_acao.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/ted_dbt/silver/pf_plano_acao.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/ted_dbt/silver/schema.yml (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/ted_dbt/views/num_transf_n_plano_acao.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/models/ted_dbt/views/schema.yml (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/profiles.yml (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/seeds/estados_brasil.csv (100%) rename {airflow_lappis/dags/dbt => dbt}/ipea/snapshots/tables_snapshot.yml (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/.user.yml (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/dbt_project.yml (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/descriptions.yml (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/macros/create_udfs.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/macros/data_quality/row_count_match.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/macros/data_quality/verificacao_tipagem.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/macros/get_custom_schema.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/macros/metadata/generate_metadata.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/macros/parse_financial_value.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/macros/schema.yml (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/macros/udfs/f_format_nc.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/macros/udfs/f_parse_dates.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/models/dados_abertos_dbt/bronze/deputados.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/models/dados_abertos_dbt/bronze/schema.yml (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/models/dados_abertos_dbt/bronze/senadores.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/models/dados_abertos_dbt/silver/parlamentares.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/models/dados_abertos_dbt/silver/schema.yml (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/models/emendas_dbt/bronze/documentos_habeis.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/models/emendas_dbt/bronze/empenhos_especiais.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/models/emendas_dbt/bronze/executor.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/models/emendas_dbt/bronze/finalidades.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/models/emendas_dbt/bronze/historico_pagamentos.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/models/emendas_dbt/bronze/metas.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/models/emendas_dbt/bronze/ordens_bancarias.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/models/emendas_dbt/bronze/planos_acoes.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/models/emendas_dbt/bronze/planos_trabalho_especial.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/models/emendas_dbt/bronze/programas.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/models/emendas_dbt/bronze/relatorio_gestao.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/models/emendas_dbt/bronze/relatorio_gestao_novo.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/models/emendas_dbt/bronze/schema.yml (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/models/emendas_dbt/bronze/tg_emendas.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/models/emendas_dbt/silver/planos_partidos.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/models/emendas_dbt/silver/schema.yml (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/models/empenhos_ted_dbt/bronze/empenhos_tesouro_ted.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/models/empenhos_ted_dbt/bronze/schema.yaml (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/models/metadata/models_metadata.sql (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/models/metadata/schema.yml (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/models/sources.yml (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/profiles.yml (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/seeds/partidos_logo.csv (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/seeds/partidos_map.csv (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/seeds/schema.yml (100%) rename {airflow_lappis/dags/dbt => dbt}/mir/tests/test_parlamentares_logo_partido.sql (100%) rename {airflow_lappis/helpers => helpers}/dados_funcionais_handler.py (100%) rename {airflow_lappis/helpers => helpers}/postgres_helpers.py (100%) rename {airflow_lappis/helpers => helpers}/retry_helpers.py (100%) rename {airflow_lappis/helpers => helpers}/safe_request.py (100%) create mode 100644 infra/README.md rename docker-compose.yml => infra/docker-compose.yml (56%) create mode 100644 infra/docker/airflow-mcp/Dockerfile create mode 100644 infra/docker/airflow/Dockerfile rename {docker => infra/docker}/postgres/init.sh (86%) create mode 100644 infra/env/.env.example rename {airflow_lappis/plugins => plugins}/cliente_base.py (100%) rename {airflow_lappis/plugins => plugins}/cliente_contratos.py (100%) rename {airflow_lappis/plugins => plugins}/cliente_deputados.py (100%) rename {airflow_lappis/plugins => plugins}/cliente_email.py (100%) rename {airflow_lappis/plugins => plugins}/cliente_github.py (100%) rename {airflow_lappis/plugins => plugins}/cliente_pncp.py (100%) rename {airflow_lappis/plugins => plugins}/cliente_postgres.py (100%) rename {airflow_lappis/plugins => plugins}/cliente_senadores.py (100%) rename {airflow_lappis/plugins => plugins}/cliente_siafi.py (100%) rename {airflow_lappis/plugins => plugins}/cliente_siape.py (100%) rename {airflow_lappis/plugins => plugins}/cliente_siorg.py (100%) rename {airflow_lappis/plugins => plugins}/cliente_ted.py (100%) rename {airflow_lappis/plugins => plugins}/cliente_transferegov_emendas.py (100%) rename {airflow_lappis/plugins => plugins}/cliente_transferegov_fundo_a_fundo.py (100%) rename {airflow_lappis/plugins => plugins}/extracao_planilhas.py (100%) rename {airflow_lappis/plugins => plugins}/schedule_loader.py (100%) delete mode 100644 superset/__init__.py rename {airflow_lappis/templates => templates}/siape/consultaDadosAfastamento.xml.j2 (100%) rename {airflow_lappis/templates => templates}/siape/consultaDadosAfastamentoHistorico.xml.j2 (100%) rename {airflow_lappis/templates => templates}/siape/consultaDadosCurriculo.xml.j2 (100%) rename {airflow_lappis/templates => templates}/siape/consultaDadosDependentes.xml.j2 (100%) rename {airflow_lappis/templates => templates}/siape/consultaDadosEscolares.xml.j2 (100%) rename {airflow_lappis/templates => templates}/siape/consultaDadosFinanceiros.xml.j2 (100%) rename {airflow_lappis/templates => templates}/siape/consultaDadosFuncionais.xml.j2 (100%) rename {airflow_lappis/templates => templates}/siape/consultaDadosPA.xml.j2 (100%) rename {airflow_lappis/templates => templates}/siape/consultaDadosPessoais.xml.j2 (100%) rename {airflow_lappis/templates => templates}/siape/consultaDadosUorg.xml.j2 (100%) rename {airflow_lappis/templates => templates}/siape/consultaPensoesInstituidas.xml.j2 (100%) rename {airflow_lappis/templates => templates}/siape/listaInformacoesAposentadoria.xml.j2 (100%) rename {airflow_lappis/templates => templates}/siape/listaServidores.xml.j2 (100%) rename {airflow_lappis/templates => templates}/siape/listaUorgs.xml.j2 (100%) diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index da1764a7..63b21896 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -19,7 +19,7 @@ env: POETRY_VERSION: "1.8.5" POETRY_VIRTUALENVS_IN_PROJECT: "true" POETRY_CACHE_DIR: "/home/runner/.cache/poetry" - DBT_PROJECT_DIR: "${{ github.workspace }}/airflow_lappis/dags/dbt/ipea" + DBT_PROJECT_DIR: "${{ github.workspace }}/dbt/ipea" IMAGE_REGISTRY_OWNER: govhub-br IMAGE_NAME: ghcr.io/govhub-br/airflow-ipea @@ -79,6 +79,7 @@ jobs: with: push: false context: . + file: ./infra/docker/airflow/Dockerfile cache-from: type=gha cache-to: type=gha,mode=max tags: | @@ -108,6 +109,7 @@ jobs: with: push: true context: . + file: ./infra/docker/airflow/Dockerfile cache-from: type=gha cache-to: type=gha,mode=max tags: | diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 7c38ad83..00000000 --- a/Dockerfile +++ /dev/null @@ -1,40 +0,0 @@ -FROM apache/airflow:2.8.1-python3.11 - -USER root -RUN apt-get update \ - && apt-get install -y --no-install-recommends \ - build-essential \ - libgtk2.0-dev \ - libgdal-dev \ - unixodbc-dev \ - libpq-dev \ - vim \ - unzip \ - git \ - curl \ - && sed -i 's,^\(MinProtocol[ ]*=\).*,\1'TLSv1.0',g' /etc/ssl/openssl.cnf \ - && sed -i 's,^\(CipherString[ ]*=\).*,\1'DEFAULT@SECLEVEL=1',g' /etc/ssl/openssl.cnf \ - && curl -O http://acraiz.icpbrasil.gov.br/credenciadas/CertificadosAC-ICP-Brasil/ACcompactado.zip \ - && unzip -o ACcompactado.zip -d /usr/local/share/ca-certificates/ \ - && update-ca-certificates \ - && apt-get autoremove -yqq --purge \ - && apt-get clean \ - && rm -rf \ - /var/lib/apt/lists/* \ - /tmp/* \ - /var/tmp/* \ - /usr/share/man \ - /usr/share/doc \ - /usr/share/doc-base \ - && sed -i 's/^# en_US.UTF-8 UTF-8$/en_US.UTF-8 UTF-8/g' /etc/locale.gen \ - && sed -i 's/^# pt_BR.UTF-8 UTF-8$/pt_BR.UTF-8 UTF-8/g' /etc/locale.gen \ - && locale-gen en_US.UTF-8 pt_BR.UTF-8 \ - && update-locale LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 - -USER airflow -WORKDIR ${AIRFLOW_HOME} - -# Para rodar o airflow só precisamos instalar as dependências visto que o código -# sempre será sincronizado via git sync ou via volumes localmente -COPY requirements.txt . -RUN pip install -r requirements.txt diff --git a/Dockerfile.superset b/Dockerfile.superset deleted file mode 100644 index 3a301ac0..00000000 --- a/Dockerfile.superset +++ /dev/null @@ -1,12 +0,0 @@ -FROM apache/superset:latest - -USER root - -# Install PostgreSQL driver directly in the virtual environment site-packages -# This ensures the driver is available when Superset tries to connect to PostgreSQL -RUN /usr/local/bin/python -m pip install psycopg2-binary --target /app/.venv/lib/python3.10/site-packages/ - -# Install other useful database drivers for future use -RUN /usr/local/bin/python -m pip install pymysql --target /app/.venv/lib/python3.10/site-packages/ - -USER superset \ No newline at end of file diff --git a/Makefile b/Makefile index fb053dcb..ca455ae7 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,9 @@ -export PYTHONPATH := $(CURDIR)/airflow_lappis -export MYPYPATH := $(CURDIR):$(CURDIR)/airflow_lappis/dags:$(CURDIR)/airflow_lappis/helpers:$(CURDIR)/airflow_lappis/plugins +COMPOSE_FILE := infra/docker-compose.yml + +export PYTHONPATH := $(CURDIR)/dags:$(CURDIR)/plugins:$(CURDIR)/helpers +export MYPYPATH := $(CURDIR):$(CURDIR)/dags:$(CURDIR)/helpers:$(CURDIR)/plugins + +.PHONY: setup format lint lint-ci test compose-config up down logs-airflow setup: pip install poetry==1.8.5 @@ -13,18 +17,30 @@ setup: format: poetry run black . poetry run ruff check --fix . - poetry run sqlfmt ./airflow_lappis/dags/dbt + poetry run sqlfmt ./dbt lint: poetry run black . --check poetry run ruff check . poetry run mypy . --explicit-package-bases --install-types --non-interactive - poetry run sqlfmt ./airflow_lappis/dags/dbt --check - [ "${GITLAB_CI}" ] || poetry run sqlfluff lint ./airflow_lappis/dags/dbt + poetry run sqlfmt ./dbt --check + [ "${GITLAB_CI}" ] || poetry run sqlfluff lint ./dbt lint-ci: - poetry run sqlfmt ./airflow_lappis/dags/dbt --check - poetry run sqlfluff lint ./airflow_lappis/dags/dbt --config .sqlfluff.ci --ignore templating + poetry run sqlfmt ./dbt --check + poetry run sqlfluff lint ./dbt --config .sqlfluff.ci --ignore templating test: poetry run pytest tests + +compose-config: + docker compose -f $(COMPOSE_FILE) config + +up: + docker compose -f $(COMPOSE_FILE) up postgres airflow airflow-mcp + +down: + docker compose -f $(COMPOSE_FILE) down + +logs-airflow: + docker compose -f $(COMPOSE_FILE) logs airflow --tail=200 diff --git a/README.md b/README.md index 97c3b701..2b284cfd 100644 --- a/README.md +++ b/README.md @@ -32,104 +32,79 @@ Esse trabalho é mantido pelo [Lab Livre](https://www.instagram.com/lab.livre/) Para dúvidas, sugestões ou para contribuir com o projeto, entre em contato conosco: [lablivreunb@gmail.com](mailto:lablivreunb@gmail.com) -# Data Pipeline Project +# Data Application MinC -This project implements a modern data stack using Airflow, dbt, Jupyter, and Superset for data orchestration, transformation, analysis, and visualization. +Este repositório organiza a aplicação de dados em torno do Airflow e do dbt. A +raiz contém o código executado pelo Airflow; a pasta `infra/` concentra Docker, +Compose e arquivos de suporte para o ambiente local. -## 🚀 Stack Components +## Stack -- **Apache Airflow**: Workflow orchestration -- **dbt**: Data transformation -- **Jupyter**: Interactive data analysis -- **Apache Superset**: Data visualization and exploration -- **Docker**: Containerization and local development -- **Make**: Build automation and setup +- **Apache Airflow**: orquestração dos pipelines +- **dbt**: transformação dos dados +- **PostgreSQL**: banco local para desenvolvimento +- **Docker Compose**: execução local dos serviços +- **Make**: automação de comandos de desenvolvimento -## 📋 Prerequisites +## Estrutura -- Docker and Docker Compose -- Make -- Python 3.x -- Git - -## 🔧 Setup - -1. Clone the repository: -```bash -git clone git@gitlab.com:lappis-unb/gest-odadosipea/app-lappis-ipea.git -cd app-lappis-ipea +```text +. +├── dags/ # DAGs carregadas pelo Airflow +│ ├── data_ingest/ +│ ├── dashboards/ +│ └── dbt/ # DAGs Cosmos que executam os projetos dbt +├── dbt/ # Projetos dbt fora do parser de DAGs +│ ├── ipea/ +│ └── mir/ +├── helpers/ # Utilitários importados pelas DAGs +├── plugins/ # Clientes e extensões usados pelo Airflow +├── templates/ # Templates Jinja/XML usados pelos clientes +├── infra/ # Docker, compose, Airflow config e init de banco +├── tests/ +├── Makefile +├── pyproject.toml +└── requirements.txt ``` -2. Run the setup using Make: +## Setup + ```bash make setup ``` -This will: -- Create necessary virtual environments -- Install dependencies -- Set up pre-commit hooks -- Configure development environment +Para usar Docker Compose, mantenha um `.env` na raiz do projeto. Um exemplo de +variáveis esperadas está em `infra/env/.env.example`. -## 🏃‍♂️ Running Locally - -Start all services using Docker Compose: +## Rodando Localmente ```bash -docker-compose up -d +make up ``` -Access the different components: -- Airflow: http://localhost:8080 -- Jupyter: http://localhost:8888 -- Superset: http://localhost:8088 - -## 💻 Development +Serviços principais: -### Code Quality +- Airflow: http://localhost:8080 +- Airflow MCP: http://localhost:8000 +- PostgreSQL: localhost:5432 -This project uses several tools to maintain code quality: -- Pre-commit hooks -- Linting configurations -- Automated testing +Comandos úteis: -Run linting checks: ```bash -make lint +make compose-config +make logs-airflow +make down ``` -Run tests: +## Desenvolvimento + ```bash +make format +make lint make test ``` -### Project Structure - -``` -. -├── airflow/ -│ ├── dags/ -│ └── plugins/ -├── dbt/ -│ └── models/ -├── jupyter/ -│ └── notebooks/ -├── superset/ -│ └── dashboards/ -├── docker-compose.yml -├── Makefile -└── README.md -``` - -### Makefile Commands - -- `make setup`: Initial project setup -- `make lint`: Run linting checks -- `make tests`: Run test suite -- `make clean`: Clean up generated files -- `make build`: Build Docker images - -## 🔐 Git Workflow +## Git Workflow This project requires signed commits. To set up GPG signing: @@ -146,13 +121,12 @@ git config --global commit.gpgsign true 3. Add your GPG key to your GitLab account -## 📚 Documentation +## Documentation - [Airflow Documentation](https://airflow.apache.org/docs/) - [dbt Documentation](https://docs.getdbt.com/) -- [Superset Documentation](https://superset.apache.org/docs/intro) -## 🤝 Contributing +## Contributing 1. Create a new branch for your feature 2. Make changes and ensure all tests pass diff --git a/airflow_lappis/airflow.cfg b/airflow_lappis/airflow.cfg deleted file mode 100644 index 081853c1..00000000 --- a/airflow_lappis/airflow.cfg +++ /dev/null @@ -1,6 +0,0 @@ -[core] -dags_folder = /opt/airflow/dags -plugins_folder = /opt/airflow/plugins - -[logging] -extra_path = /opt/airflow/helpers diff --git a/dags/.airflowignore b/dags/.airflowignore new file mode 100644 index 00000000..6a7ef6a1 --- /dev/null +++ b/dags/.airflowignore @@ -0,0 +1,7 @@ +__pycache__/ +*.pyc +.ipynb_checkpoints/ +README.md +**/target/ +**/dbt_packages/ +**/logs/ diff --git a/airflow_lappis/dags/dashboards/__init__.py b/dags/dashboards/__init__.py similarity index 100% rename from airflow_lappis/dags/dashboards/__init__.py rename to dags/dashboards/__init__.py diff --git a/airflow_lappis/dags/dashboards/dashboard_servidores_dag.py b/dags/dashboards/dashboard_servidores_dag.py similarity index 100% rename from airflow_lappis/dags/dashboards/dashboard_servidores_dag.py rename to dags/dashboards/dashboard_servidores_dag.py diff --git a/airflow_lappis/dags/data_ingest/compras_gov/contratos_inativos_ingest_dag.py b/dags/data_ingest/compras_gov/contratos_inativos_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/compras_gov/contratos_inativos_ingest_dag.py rename to dags/data_ingest/compras_gov/contratos_inativos_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/compras_gov/contratos_ingest_dag.py b/dags/data_ingest/compras_gov/contratos_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/compras_gov/contratos_ingest_dag.py rename to dags/data_ingest/compras_gov/contratos_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/compras_gov/cronograma_ingest_dag.py b/dags/data_ingest/compras_gov/cronograma_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/compras_gov/cronograma_ingest_dag.py rename to dags/data_ingest/compras_gov/cronograma_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/compras_gov/empenhos_ingest_dag.py b/dags/data_ingest/compras_gov/empenhos_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/compras_gov/empenhos_ingest_dag.py rename to dags/data_ingest/compras_gov/empenhos_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/compras_gov/faturas_ingest_dag.py b/dags/data_ingest/compras_gov/faturas_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/compras_gov/faturas_ingest_dag.py rename to dags/data_ingest/compras_gov/faturas_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/compras_gov/terceirizados_ingest_dag.py b/dags/data_ingest/compras_gov/terceirizados_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/compras_gov/terceirizados_ingest_dag.py rename to dags/data_ingest/compras_gov/terceirizados_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/dados_abertos/deputados_ingest_dag.py b/dags/data_ingest/dados_abertos/deputados_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/dados_abertos/deputados_ingest_dag.py rename to dags/data_ingest/dados_abertos/deputados_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/dados_abertos/senadores_ingest_dag.py b/dags/data_ingest/dados_abertos/senadores_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/dados_abertos/senadores_ingest_dag.py rename to dags/data_ingest/dados_abertos/senadores_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/pncp/itens_resultados_licitacoes.py b/dags/data_ingest/pncp/itens_resultados_licitacoes.py similarity index 100% rename from airflow_lappis/dags/data_ingest/pncp/itens_resultados_licitacoes.py rename to dags/data_ingest/pncp/itens_resultados_licitacoes.py diff --git a/airflow_lappis/dags/data_ingest/pncp/licitacoes_ingest.py b/dags/data_ingest/pncp/licitacoes_ingest.py similarity index 100% rename from airflow_lappis/dags/data_ingest/pncp/licitacoes_ingest.py rename to dags/data_ingest/pncp/licitacoes_ingest.py diff --git a/airflow_lappis/dags/data_ingest/sgac/projetos_sgac_ingest_dag.py b/dags/data_ingest/sgac/projetos_sgac_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/sgac/projetos_sgac_ingest_dag.py rename to dags/data_ingest/sgac/projetos_sgac_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/siafi/nota_credito_siafi_ingest_dag.py b/dags/data_ingest/siafi/nota_credito_siafi_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/siafi/nota_credito_siafi_ingest_dag.py rename to dags/data_ingest/siafi/nota_credito_siafi_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/siafi/nota_empenho_siafi_ingest_dag.py b/dags/data_ingest/siafi/nota_empenho_siafi_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/siafi/nota_empenho_siafi_ingest_dag.py rename to dags/data_ingest/siafi/nota_empenho_siafi_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/siafi/programacao_financeira_siafi_ingest_dag.py b/dags/data_ingest/siafi/programacao_financeira_siafi_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/siafi/programacao_financeira_siafi_ingest_dag.py rename to dags/data_ingest/siafi/programacao_financeira_siafi_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/siape/dados_afastamento_historico_siape_ingest_dag.py b/dags/data_ingest/siape/dados_afastamento_historico_siape_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/siape/dados_afastamento_historico_siape_ingest_dag.py rename to dags/data_ingest/siape/dados_afastamento_historico_siape_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/siape/dados_afastamento_siape_ingest_dag.py b/dags/data_ingest/siape/dados_afastamento_siape_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/siape/dados_afastamento_siape_ingest_dag.py rename to dags/data_ingest/siape/dados_afastamento_siape_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/siape/dados_curriculo_siape_ingest_dag.py b/dags/data_ingest/siape/dados_curriculo_siape_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/siape/dados_curriculo_siape_ingest_dag.py rename to dags/data_ingest/siape/dados_curriculo_siape_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/siape/dados_dependentes_siape_ingest_dag.py b/dags/data_ingest/siape/dados_dependentes_siape_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/siape/dados_dependentes_siape_ingest_dag.py rename to dags/data_ingest/siape/dados_dependentes_siape_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/siape/dados_escolares_siape_ingest_dag.py b/dags/data_ingest/siape/dados_escolares_siape_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/siape/dados_escolares_siape_ingest_dag.py rename to dags/data_ingest/siape/dados_escolares_siape_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/siape/dados_financeiros_siape_dag.py b/dags/data_ingest/siape/dados_financeiros_siape_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/siape/dados_financeiros_siape_dag.py rename to dags/data_ingest/siape/dados_financeiros_siape_dag.py diff --git a/airflow_lappis/dags/data_ingest/siape/dados_funcionais_siape_ingest_dag.py b/dags/data_ingest/siape/dados_funcionais_siape_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/siape/dados_funcionais_siape_ingest_dag.py rename to dags/data_ingest/siape/dados_funcionais_siape_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/siape/dados_pa_siape_ingest_dag.py b/dags/data_ingest/siape/dados_pa_siape_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/siape/dados_pa_siape_ingest_dag.py rename to dags/data_ingest/siape/dados_pa_siape_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/siape/dados_pessoais_siape_ingest_dag.py b/dags/data_ingest/siape/dados_pessoais_siape_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/siape/dados_pessoais_siape_ingest_dag.py rename to dags/data_ingest/siape/dados_pessoais_siape_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/siape/dados_uorg_siape_ingest_dag.py b/dags/data_ingest/siape/dados_uorg_siape_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/siape/dados_uorg_siape_ingest_dag.py rename to dags/data_ingest/siape/dados_uorg_siape_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/siape/lista_aposentadoria_siape_ingest_dag.py b/dags/data_ingest/siape/lista_aposentadoria_siape_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/siape/lista_aposentadoria_siape_ingest_dag.py rename to dags/data_ingest/siape/lista_aposentadoria_siape_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/siape/lista_servidores_siape_ingest_dag.py b/dags/data_ingest/siape/lista_servidores_siape_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/siape/lista_servidores_siape_ingest_dag.py rename to dags/data_ingest/siape/lista_servidores_siape_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/siape/lista_uorgs_siape_ingest_dag.py b/dags/data_ingest/siape/lista_uorgs_siape_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/siape/lista_uorgs_siape_ingest_dag.py rename to dags/data_ingest/siape/lista_uorgs_siape_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/siape/pensoes_instituidas_siape_ingest_dag.py b/dags/data_ingest/siape/pensoes_instituidas_siape_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/siape/pensoes_instituidas_siape_ingest_dag.py rename to dags/data_ingest/siape/pensoes_instituidas_siape_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/siorg/cargos_funcao_ingest_dag.py b/dags/data_ingest/siorg/cargos_funcao_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/siorg/cargos_funcao_ingest_dag.py rename to dags/data_ingest/siorg/cargos_funcao_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/siorg/estrutura_organizacional_cargos_ingest_dag.py b/dags/data_ingest/siorg/estrutura_organizacional_cargos_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/siorg/estrutura_organizacional_cargos_ingest_dag.py rename to dags/data_ingest/siorg/estrutura_organizacional_cargos_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/siorg/unidade_organizacional_ingest_dag.py b/dags/data_ingest/siorg/unidade_organizacional_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/siorg/unidade_organizacional_ingest_dag.py rename to dags/data_ingest/siorg/unidade_organizacional_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/tesouro_gerencial/empenhos_tesouro_emendas_ingest_dag.py b/dags/data_ingest/tesouro_gerencial/empenhos_tesouro_emendas_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/tesouro_gerencial/empenhos_tesouro_emendas_ingest_dag.py rename to dags/data_ingest/tesouro_gerencial/empenhos_tesouro_emendas_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/tesouro_gerencial/empenhos_tesouro_ingest_dag.py b/dags/data_ingest/tesouro_gerencial/empenhos_tesouro_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/tesouro_gerencial/empenhos_tesouro_ingest_dag.py rename to dags/data_ingest/tesouro_gerencial/empenhos_tesouro_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/tesouro_gerencial/mcid/dotacao_execucao_outras_fontes_mcid_ingest_dag.py b/dags/data_ingest/tesouro_gerencial/mcid/dotacao_execucao_outras_fontes_mcid_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/tesouro_gerencial/mcid/dotacao_execucao_outras_fontes_mcid_ingest_dag.py rename to dags/data_ingest/tesouro_gerencial/mcid/dotacao_execucao_outras_fontes_mcid_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/tesouro_gerencial/mcid/empenho_emendas_parlamentares_ingest_dag.py b/dags/data_ingest/tesouro_gerencial/mcid/empenho_emendas_parlamentares_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/tesouro_gerencial/mcid/empenho_emendas_parlamentares_ingest_dag.py rename to dags/data_ingest/tesouro_gerencial/mcid/empenho_emendas_parlamentares_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/tesouro_gerencial/mcid/orcamento_mcid_por_acao_ingest_dag.py b/dags/data_ingest/tesouro_gerencial/mcid/orcamento_mcid_por_acao_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/tesouro_gerencial/mcid/orcamento_mcid_por_acao_ingest_dag.py rename to dags/data_ingest/tesouro_gerencial/mcid/orcamento_mcid_por_acao_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/tesouro_gerencial/mir/empenhos_tesouro_parlamentares_ingest_dag.py b/dags/data_ingest/tesouro_gerencial/mir/empenhos_tesouro_parlamentares_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/tesouro_gerencial/mir/empenhos_tesouro_parlamentares_ingest_dag.py rename to dags/data_ingest/tesouro_gerencial/mir/empenhos_tesouro_parlamentares_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/tesouro_gerencial/nc_tesouro_ingest.dag.py b/dags/data_ingest/tesouro_gerencial/nc_tesouro_ingest.dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/tesouro_gerencial/nc_tesouro_ingest.dag.py rename to dags/data_ingest/tesouro_gerencial/nc_tesouro_ingest.dag.py diff --git a/airflow_lappis/dags/data_ingest/tesouro_gerencial/pf_tesouro_ingest_dag.py b/dags/data_ingest/tesouro_gerencial/pf_tesouro_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/tesouro_gerencial/pf_tesouro_ingest_dag.py rename to dags/data_ingest/tesouro_gerencial/pf_tesouro_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/tesouro_gerencial/visao_orcamentaria_ingest.py b/dags/data_ingest/tesouro_gerencial/visao_orcamentaria_ingest.py similarity index 100% rename from airflow_lappis/dags/data_ingest/tesouro_gerencial/visao_orcamentaria_ingest.py rename to dags/data_ingest/tesouro_gerencial/visao_orcamentaria_ingest.py diff --git a/airflow_lappis/dags/data_ingest/transfere_gov/minc/api_programas_dag.py b/dags/data_ingest/transfere_gov/minc/api_programas_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/transfere_gov/minc/api_programas_dag.py rename to dags/data_ingest/transfere_gov/minc/api_programas_dag.py diff --git a/airflow_lappis/dags/data_ingest/transfere_gov/minc/minc_api_anexos_relatorios_dag.py b/dags/data_ingest/transfere_gov/minc/minc_api_anexos_relatorios_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/transfere_gov/minc/minc_api_anexos_relatorios_dag.py rename to dags/data_ingest/transfere_gov/minc/minc_api_anexos_relatorios_dag.py diff --git a/airflow_lappis/dags/data_ingest/transfere_gov/minc/minc_api_planos_acao_dag.py b/dags/data_ingest/transfere_gov/minc/minc_api_planos_acao_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/transfere_gov/minc/minc_api_planos_acao_dag.py rename to dags/data_ingest/transfere_gov/minc/minc_api_planos_acao_dag.py diff --git a/airflow_lappis/dags/data_ingest/transfere_gov/minc/minc_api_relatorios_gestao_dag.py b/dags/data_ingest/transfere_gov/minc/minc_api_relatorios_gestao_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/transfere_gov/minc/minc_api_relatorios_gestao_dag.py rename to dags/data_ingest/transfere_gov/minc/minc_api_relatorios_gestao_dag.py diff --git a/airflow_lappis/dags/data_ingest/transfere_gov/minc/minc_download_anexos_dag.py b/dags/data_ingest/transfere_gov/minc/minc_download_anexos_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/transfere_gov/minc/minc_download_anexos_dag.py rename to dags/data_ingest/transfere_gov/minc/minc_download_anexos_dag.py diff --git a/airflow_lappis/dags/data_ingest/transfere_gov/minc/minc_extracao_anexos_dag.py b/dags/data_ingest/transfere_gov/minc/minc_extracao_anexos_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/transfere_gov/minc/minc_extracao_anexos_dag.py rename to dags/data_ingest/transfere_gov/minc/minc_extracao_anexos_dag.py diff --git a/airflow_lappis/dags/data_ingest/transfere_gov/mir/notas_de_credito_ingest_mir_dag.py b/dags/data_ingest/transfere_gov/mir/notas_de_credito_ingest_mir_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/transfere_gov/mir/notas_de_credito_ingest_mir_dag.py rename to dags/data_ingest/transfere_gov/mir/notas_de_credito_ingest_mir_dag.py diff --git a/airflow_lappis/dags/data_ingest/transfere_gov/mir/plano_acao_ingest_mir_dag.py b/dags/data_ingest/transfere_gov/mir/plano_acao_ingest_mir_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/transfere_gov/mir/plano_acao_ingest_mir_dag.py rename to dags/data_ingest/transfere_gov/mir/plano_acao_ingest_mir_dag.py diff --git a/airflow_lappis/dags/data_ingest/transfere_gov/mir/programa_financeira_ingest_mir_dag.py b/dags/data_ingest/transfere_gov/mir/programa_financeira_ingest_mir_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/transfere_gov/mir/programa_financeira_ingest_mir_dag.py rename to dags/data_ingest/transfere_gov/mir/programa_financeira_ingest_mir_dag.py diff --git a/airflow_lappis/dags/data_ingest/transfere_gov/mir/programas_ingest_mir_dag.py b/dags/data_ingest/transfere_gov/mir/programas_ingest_mir_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/transfere_gov/mir/programas_ingest_mir_dag.py rename to dags/data_ingest/transfere_gov/mir/programas_ingest_mir_dag.py diff --git a/airflow_lappis/dags/data_ingest/transfere_gov/notas_de_credito_ingest_dag.py b/dags/data_ingest/transfere_gov/notas_de_credito_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/transfere_gov/notas_de_credito_ingest_dag.py rename to dags/data_ingest/transfere_gov/notas_de_credito_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/transfere_gov/plano_acao_ingest_dag.py b/dags/data_ingest/transfere_gov/plano_acao_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/transfere_gov/plano_acao_ingest_dag.py rename to dags/data_ingest/transfere_gov/plano_acao_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/transfere_gov/programa_beneficiario_ingest_dag.py b/dags/data_ingest/transfere_gov/programa_beneficiario_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/transfere_gov/programa_beneficiario_ingest_dag.py rename to dags/data_ingest/transfere_gov/programa_beneficiario_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/transfere_gov/programacao_financeira_ingest_dag.py b/dags/data_ingest/transfere_gov/programacao_financeira_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/transfere_gov/programacao_financeira_ingest_dag.py rename to dags/data_ingest/transfere_gov/programacao_financeira_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/transfere_gov/programas_ingest_dag.py b/dags/data_ingest/transfere_gov/programas_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/transfere_gov/programas_ingest_dag.py rename to dags/data_ingest/transfere_gov/programas_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/transferegov_emendas/documentos_habeis_especias_ingest_dag.py b/dags/data_ingest/transferegov_emendas/documentos_habeis_especias_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/transferegov_emendas/documentos_habeis_especias_ingest_dag.py rename to dags/data_ingest/transferegov_emendas/documentos_habeis_especias_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/transferegov_emendas/empenhos_especiais_ingest_dag.py b/dags/data_ingest/transferegov_emendas/empenhos_especiais_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/transferegov_emendas/empenhos_especiais_ingest_dag.py rename to dags/data_ingest/transferegov_emendas/empenhos_especiais_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/transferegov_emendas/executor_especial_ingest_dag.py b/dags/data_ingest/transferegov_emendas/executor_especial_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/transferegov_emendas/executor_especial_ingest_dag.py rename to dags/data_ingest/transferegov_emendas/executor_especial_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/transferegov_emendas/finalidade_especial_ingest_dag.py b/dags/data_ingest/transferegov_emendas/finalidade_especial_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/transferegov_emendas/finalidade_especial_ingest_dag.py rename to dags/data_ingest/transferegov_emendas/finalidade_especial_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/transferegov_emendas/historico_pagamentos_especiais_ingest_dag.py b/dags/data_ingest/transferegov_emendas/historico_pagamentos_especiais_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/transferegov_emendas/historico_pagamentos_especiais_ingest_dag.py rename to dags/data_ingest/transferegov_emendas/historico_pagamentos_especiais_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/transferegov_emendas/metas_especiais_ingest_dag.py b/dags/data_ingest/transferegov_emendas/metas_especiais_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/transferegov_emendas/metas_especiais_ingest_dag.py rename to dags/data_ingest/transferegov_emendas/metas_especiais_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/transferegov_emendas/ordem_bancaria_especial_ingest_dag.py b/dags/data_ingest/transferegov_emendas/ordem_bancaria_especial_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/transferegov_emendas/ordem_bancaria_especial_ingest_dag.py rename to dags/data_ingest/transferegov_emendas/ordem_bancaria_especial_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/transferegov_emendas/plano_trabalho_especial_ingest_dag.py b/dags/data_ingest/transferegov_emendas/plano_trabalho_especial_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/transferegov_emendas/plano_trabalho_especial_ingest_dag.py rename to dags/data_ingest/transferegov_emendas/plano_trabalho_especial_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/transferegov_emendas/planos_acao_especiais_ingest_dag.py b/dags/data_ingest/transferegov_emendas/planos_acao_especiais_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/transferegov_emendas/planos_acao_especiais_ingest_dag.py rename to dags/data_ingest/transferegov_emendas/planos_acao_especiais_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/transferegov_emendas/programas_especiais_ingest_dag.py b/dags/data_ingest/transferegov_emendas/programas_especiais_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/transferegov_emendas/programas_especiais_ingest_dag.py rename to dags/data_ingest/transferegov_emendas/programas_especiais_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/transferegov_emendas/relatorio_gestao_novo_especial_ingest_dag.py b/dags/data_ingest/transferegov_emendas/relatorio_gestao_novo_especial_ingest_dag.py similarity index 100% rename from airflow_lappis/dags/data_ingest/transferegov_emendas/relatorio_gestao_novo_especial_ingest_dag.py rename to dags/data_ingest/transferegov_emendas/relatorio_gestao_novo_especial_ingest_dag.py diff --git a/airflow_lappis/dags/data_ingest/transferegov_emendas/reltorio_gestao_ingest.py b/dags/data_ingest/transferegov_emendas/reltorio_gestao_ingest.py similarity index 100% rename from airflow_lappis/dags/data_ingest/transferegov_emendas/reltorio_gestao_ingest.py rename to dags/data_ingest/transferegov_emendas/reltorio_gestao_ingest.py diff --git a/airflow_lappis/dags/dbt/ipea/cosmos_dag.py b/dags/dbt/ipea_cosmos_dag.py similarity index 89% rename from airflow_lappis/dags/dbt/ipea/cosmos_dag.py rename to dags/dbt/ipea_cosmos_dag.py index 2e30ded1..10a62bfc 100755 --- a/airflow_lappis/dags/dbt/ipea/cosmos_dag.py +++ b/dags/dbt/ipea_cosmos_dag.py @@ -8,13 +8,13 @@ os.environ[DBT_LOG_PATH_ENVVAR] = dbt_log_path profile_config = ProfileConfig( - profiles_yml_filepath=f"{os.environ['AIRFLOW_REPO_BASE']}/dags/dbt/ipea/profiles.yml", + profiles_yml_filepath=f"{os.environ['AIRFLOW_REPO_BASE']}/dbt/ipea/profiles.yml", profile_name="ipea", target_name="prod", ) my_cosmos_dag = DbtDag( - project_config=ProjectConfig(f"{os.environ['AIRFLOW_REPO_BASE']}/dags/dbt/ipea"), + project_config=ProjectConfig(f"{os.environ['AIRFLOW_REPO_BASE']}/dbt/ipea"), profile_config=profile_config, execution_config=ExecutionConfig( dbt_executable_path=f"{os.environ['AIRFLOW_REPO_BASE']}/.local/bin/dbt", diff --git a/airflow_lappis/dags/dbt/mir/cosmos_dag.py b/dags/dbt/mir_cosmos_dag.py similarity index 89% rename from airflow_lappis/dags/dbt/mir/cosmos_dag.py rename to dags/dbt/mir_cosmos_dag.py index e139edeb..cc890f2b 100755 --- a/airflow_lappis/dags/dbt/mir/cosmos_dag.py +++ b/dags/dbt/mir_cosmos_dag.py @@ -8,13 +8,13 @@ os.environ[DBT_LOG_PATH_ENVVAR] = dbt_log_path profile_config = ProfileConfig( - profiles_yml_filepath=f"{os.environ['AIRFLOW_REPO_BASE']}/dags/dbt/mir/profiles.yml", + profiles_yml_filepath=f"{os.environ['AIRFLOW_REPO_BASE']}/dbt/mir/profiles.yml", profile_name="mir", target_name="prod", ) my_cosmos_dag = DbtDag( - project_config=ProjectConfig(f"{os.environ['AIRFLOW_REPO_BASE']}/dags/dbt/mir"), + project_config=ProjectConfig(f"{os.environ['AIRFLOW_REPO_BASE']}/dbt/mir"), profile_config=profile_config, execution_config=ExecutionConfig( dbt_executable_path=f"{os.environ['AIRFLOW_REPO_BASE']}/.local/bin/dbt", diff --git a/airflow_lappis/dags/dbt/.user.yml b/dbt/.user.yml similarity index 100% rename from airflow_lappis/dags/dbt/.user.yml rename to dbt/.user.yml diff --git a/airflow_lappis/dags/dbt/ipea/.user.yml b/dbt/ipea/.user.yml similarity index 100% rename from airflow_lappis/dags/dbt/ipea/.user.yml rename to dbt/ipea/.user.yml diff --git a/airflow_lappis/dags/dbt/ipea/dbt_project.yml b/dbt/ipea/dbt_project.yml similarity index 100% rename from airflow_lappis/dags/dbt/ipea/dbt_project.yml rename to dbt/ipea/dbt_project.yml diff --git a/airflow_lappis/dags/dbt/ipea/descriptions.yml b/dbt/ipea/descriptions.yml similarity index 100% rename from airflow_lappis/dags/dbt/ipea/descriptions.yml rename to dbt/ipea/descriptions.yml diff --git a/airflow_lappis/dags/dbt/ipea/macros/create_udfs.sql b/dbt/ipea/macros/create_udfs.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/macros/create_udfs.sql rename to dbt/ipea/macros/create_udfs.sql diff --git a/airflow_lappis/dags/dbt/ipea/macros/data_quality/row_count_match.sql b/dbt/ipea/macros/data_quality/row_count_match.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/macros/data_quality/row_count_match.sql rename to dbt/ipea/macros/data_quality/row_count_match.sql diff --git a/airflow_lappis/dags/dbt/ipea/macros/data_quality/verificacao_tipagem.sql b/dbt/ipea/macros/data_quality/verificacao_tipagem.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/macros/data_quality/verificacao_tipagem.sql rename to dbt/ipea/macros/data_quality/verificacao_tipagem.sql diff --git a/airflow_lappis/dags/dbt/ipea/macros/get_custom_schema.sql b/dbt/ipea/macros/get_custom_schema.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/macros/get_custom_schema.sql rename to dbt/ipea/macros/get_custom_schema.sql diff --git a/airflow_lappis/dags/dbt/ipea/macros/metadata/generate_metadata.sql b/dbt/ipea/macros/metadata/generate_metadata.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/macros/metadata/generate_metadata.sql rename to dbt/ipea/macros/metadata/generate_metadata.sql diff --git a/airflow_lappis/dags/dbt/ipea/macros/parse_financial_value.sql b/dbt/ipea/macros/parse_financial_value.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/macros/parse_financial_value.sql rename to dbt/ipea/macros/parse_financial_value.sql diff --git a/airflow_lappis/dags/dbt/ipea/macros/schema.yml b/dbt/ipea/macros/schema.yml similarity index 100% rename from airflow_lappis/dags/dbt/ipea/macros/schema.yml rename to dbt/ipea/macros/schema.yml diff --git a/airflow_lappis/dags/dbt/ipea/macros/udfs/f_format_nc.sql b/dbt/ipea/macros/udfs/f_format_nc.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/macros/udfs/f_format_nc.sql rename to dbt/ipea/macros/udfs/f_format_nc.sql diff --git a/airflow_lappis/dags/dbt/ipea/macros/udfs/f_parse_dates.sql b/dbt/ipea/macros/udfs/f_parse_dates.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/macros/udfs/f_parse_dates.sql rename to dbt/ipea/macros/udfs/f_parse_dates.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/contratos_dbt/bronze/contratos.sql b/dbt/ipea/models/contratos_dbt/bronze/contratos.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/contratos_dbt/bronze/contratos.sql rename to dbt/ipea/models/contratos_dbt/bronze/contratos.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/contratos_dbt/bronze/cronogramas.sql b/dbt/ipea/models/contratos_dbt/bronze/cronogramas.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/contratos_dbt/bronze/cronogramas.sql rename to dbt/ipea/models/contratos_dbt/bronze/cronogramas.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/contratos_dbt/bronze/empenhos.sql b/dbt/ipea/models/contratos_dbt/bronze/empenhos.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/contratos_dbt/bronze/empenhos.sql rename to dbt/ipea/models/contratos_dbt/bronze/empenhos.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/contratos_dbt/bronze/empenhos_tesouro.sql b/dbt/ipea/models/contratos_dbt/bronze/empenhos_tesouro.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/contratos_dbt/bronze/empenhos_tesouro.sql rename to dbt/ipea/models/contratos_dbt/bronze/empenhos_tesouro.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/contratos_dbt/bronze/faturas.sql b/dbt/ipea/models/contratos_dbt/bronze/faturas.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/contratos_dbt/bronze/faturas.sql rename to dbt/ipea/models/contratos_dbt/bronze/faturas.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/contratos_dbt/bronze/schema.yml b/dbt/ipea/models/contratos_dbt/bronze/schema.yml similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/contratos_dbt/bronze/schema.yml rename to dbt/ipea/models/contratos_dbt/bronze/schema.yml diff --git a/airflow_lappis/dags/dbt/ipea/models/contratos_dbt/gold/contratos_comparativo_mensal.sql b/dbt/ipea/models/contratos_dbt/gold/contratos_comparativo_mensal.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/contratos_dbt/gold/contratos_comparativo_mensal.sql rename to dbt/ipea/models/contratos_dbt/gold/contratos_comparativo_mensal.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/contratos_dbt/gold/contratos_resumo.sql b/dbt/ipea/models/contratos_dbt/gold/contratos_resumo.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/contratos_dbt/gold/contratos_resumo.sql rename to dbt/ipea/models/contratos_dbt/gold/contratos_resumo.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/contratos_dbt/gold/contratos_somatorio.sql b/dbt/ipea/models/contratos_dbt/gold/contratos_somatorio.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/contratos_dbt/gold/contratos_somatorio.sql rename to dbt/ipea/models/contratos_dbt/gold/contratos_somatorio.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/contratos_dbt/gold/schema.yml b/dbt/ipea/models/contratos_dbt/gold/schema.yml similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/contratos_dbt/gold/schema.yml rename to dbt/ipea/models/contratos_dbt/gold/schema.yml diff --git a/airflow_lappis/dags/dbt/ipea/models/contratos_dbt/silver/contratos_empenhos.sql b/dbt/ipea/models/contratos_dbt/silver/contratos_empenhos.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/contratos_dbt/silver/contratos_empenhos.sql rename to dbt/ipea/models/contratos_dbt/silver/contratos_empenhos.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/contratos_dbt/silver/contratos_estagios.sql b/dbt/ipea/models/contratos_dbt/silver/contratos_estagios.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/contratos_dbt/silver/contratos_estagios.sql rename to dbt/ipea/models/contratos_dbt/silver/contratos_estagios.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/contratos_dbt/silver/contratos_faturas.sql b/dbt/ipea/models/contratos_dbt/silver/contratos_faturas.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/contratos_dbt/silver/contratos_faturas.sql rename to dbt/ipea/models/contratos_dbt/silver/contratos_faturas.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/contratos_dbt/silver/cronogramas_faturas_mensal.sql b/dbt/ipea/models/contratos_dbt/silver/cronogramas_faturas_mensal.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/contratos_dbt/silver/cronogramas_faturas_mensal.sql rename to dbt/ipea/models/contratos_dbt/silver/cronogramas_faturas_mensal.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/contratos_dbt/silver/estagios_mensal.sql b/dbt/ipea/models/contratos_dbt/silver/estagios_mensal.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/contratos_dbt/silver/estagios_mensal.sql rename to dbt/ipea/models/contratos_dbt/silver/estagios_mensal.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/contratos_dbt/silver/schema.yml b/dbt/ipea/models/contratos_dbt/silver/schema.yml similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/contratos_dbt/silver/schema.yml rename to dbt/ipea/models/contratos_dbt/silver/schema.yml diff --git a/airflow_lappis/dags/dbt/ipea/models/contratos_dbt/views/identificadores.sql b/dbt/ipea/models/contratos_dbt/views/identificadores.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/contratos_dbt/views/identificadores.sql rename to dbt/ipea/models/contratos_dbt/views/identificadores.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/contratos_dbt/views/preenchimento_meses.sql b/dbt/ipea/models/contratos_dbt/views/preenchimento_meses.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/contratos_dbt/views/preenchimento_meses.sql rename to dbt/ipea/models/contratos_dbt/views/preenchimento_meses.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/contratos_dbt/views/schema.yml b/dbt/ipea/models/contratos_dbt/views/schema.yml similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/contratos_dbt/views/schema.yml rename to dbt/ipea/models/contratos_dbt/views/schema.yml diff --git a/airflow_lappis/dags/dbt/ipea/models/metadata/models_metadata.sql b/dbt/ipea/models/metadata/models_metadata.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/metadata/models_metadata.sql rename to dbt/ipea/models/metadata/models_metadata.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/metadata/schema.yml b/dbt/ipea/models/metadata/schema.yml similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/metadata/schema.yml rename to dbt/ipea/models/metadata/schema.yml diff --git a/airflow_lappis/dags/dbt/ipea/models/orcamento_dbt/bronze/schema.yml b/dbt/ipea/models/orcamento_dbt/bronze/schema.yml similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/orcamento_dbt/bronze/schema.yml rename to dbt/ipea/models/orcamento_dbt/bronze/schema.yml diff --git a/airflow_lappis/dags/dbt/ipea/models/orcamento_dbt/bronze/visao_orcamentaria_total.sql b/dbt/ipea/models/orcamento_dbt/bronze/visao_orcamentaria_total.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/orcamento_dbt/bronze/visao_orcamentaria_total.sql rename to dbt/ipea/models/orcamento_dbt/bronze/visao_orcamentaria_total.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/bronze/afastamento_historico.sql b/dbt/ipea/models/pessoas_dbt/bronze/afastamento_historico.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/bronze/afastamento_historico.sql rename to dbt/ipea/models/pessoas_dbt/bronze/afastamento_historico.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/bronze/cargos_funcoes.sql b/dbt/ipea/models/pessoas_dbt/bronze/cargos_funcoes.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/bronze/cargos_funcoes.sql rename to dbt/ipea/models/pessoas_dbt/bronze/cargos_funcoes.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/bronze/dados_afastamento.sql b/dbt/ipea/models/pessoas_dbt/bronze/dados_afastamento.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/bronze/dados_afastamento.sql rename to dbt/ipea/models/pessoas_dbt/bronze/dados_afastamento.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/bronze/dados_curriculo.sql b/dbt/ipea/models/pessoas_dbt/bronze/dados_curriculo.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/bronze/dados_curriculo.sql rename to dbt/ipea/models/pessoas_dbt/bronze/dados_curriculo.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/bronze/dados_dependentes.sql b/dbt/ipea/models/pessoas_dbt/bronze/dados_dependentes.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/bronze/dados_dependentes.sql rename to dbt/ipea/models/pessoas_dbt/bronze/dados_dependentes.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/bronze/dados_escolares.sql b/dbt/ipea/models/pessoas_dbt/bronze/dados_escolares.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/bronze/dados_escolares.sql rename to dbt/ipea/models/pessoas_dbt/bronze/dados_escolares.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/bronze/dados_financeiros.sql b/dbt/ipea/models/pessoas_dbt/bronze/dados_financeiros.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/bronze/dados_financeiros.sql rename to dbt/ipea/models/pessoas_dbt/bronze/dados_financeiros.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/bronze/dados_funcionais.sql b/dbt/ipea/models/pessoas_dbt/bronze/dados_funcionais.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/bronze/dados_funcionais.sql rename to dbt/ipea/models/pessoas_dbt/bronze/dados_funcionais.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/bronze/dados_pa.sql b/dbt/ipea/models/pessoas_dbt/bronze/dados_pa.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/bronze/dados_pa.sql rename to dbt/ipea/models/pessoas_dbt/bronze/dados_pa.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/bronze/dados_pessoais.sql b/dbt/ipea/models/pessoas_dbt/bronze/dados_pessoais.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/bronze/dados_pessoais.sql rename to dbt/ipea/models/pessoas_dbt/bronze/dados_pessoais.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/bronze/dados_uorg.sql b/dbt/ipea/models/pessoas_dbt/bronze/dados_uorg.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/bronze/dados_uorg.sql rename to dbt/ipea/models/pessoas_dbt/bronze/dados_uorg.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/bronze/estrutura_organizacional_cargos.sql b/dbt/ipea/models/pessoas_dbt/bronze/estrutura_organizacional_cargos.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/bronze/estrutura_organizacional_cargos.sql rename to dbt/ipea/models/pessoas_dbt/bronze/estrutura_organizacional_cargos.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/bronze/lista_servidores.sql b/dbt/ipea/models/pessoas_dbt/bronze/lista_servidores.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/bronze/lista_servidores.sql rename to dbt/ipea/models/pessoas_dbt/bronze/lista_servidores.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/bronze/lista_uorgs.sql b/dbt/ipea/models/pessoas_dbt/bronze/lista_uorgs.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/bronze/lista_uorgs.sql rename to dbt/ipea/models/pessoas_dbt/bronze/lista_uorgs.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/bronze/schema.yml b/dbt/ipea/models/pessoas_dbt/bronze/schema.yml similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/bronze/schema.yml rename to dbt/ipea/models/pessoas_dbt/bronze/schema.yml diff --git a/airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/bronze/terceirizados.sql b/dbt/ipea/models/pessoas_dbt/bronze/terceirizados.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/bronze/terceirizados.sql rename to dbt/ipea/models/pessoas_dbt/bronze/terceirizados.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/bronze/unidade_organizacional.sql b/dbt/ipea/models/pessoas_dbt/bronze/unidade_organizacional.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/bronze/unidade_organizacional.sql rename to dbt/ipea/models/pessoas_dbt/bronze/unidade_organizacional.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/gold/aposentadorias_resumo.sql b/dbt/ipea/models/pessoas_dbt/gold/aposentadorias_resumo.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/gold/aposentadorias_resumo.sql rename to dbt/ipea/models/pessoas_dbt/gold/aposentadorias_resumo.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/gold/cargos_consolidado.sql b/dbt/ipea/models/pessoas_dbt/gold/cargos_consolidado.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/gold/cargos_consolidado.sql rename to dbt/ipea/models/pessoas_dbt/gold/cargos_consolidado.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/gold/distribuicao_genero.sql b/dbt/ipea/models/pessoas_dbt/gold/distribuicao_genero.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/gold/distribuicao_genero.sql rename to dbt/ipea/models/pessoas_dbt/gold/distribuicao_genero.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/gold/distribuicao_mapa_uf.sql b/dbt/ipea/models/pessoas_dbt/gold/distribuicao_mapa_uf.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/gold/distribuicao_mapa_uf.sql rename to dbt/ipea/models/pessoas_dbt/gold/distribuicao_mapa_uf.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/gold/distribuicao_raca_cor.sql b/dbt/ipea/models/pessoas_dbt/gold/distribuicao_raca_cor.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/gold/distribuicao_raca_cor.sql rename to dbt/ipea/models/pessoas_dbt/gold/distribuicao_raca_cor.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/gold/distribuicao_situacao_funcional.sql b/dbt/ipea/models/pessoas_dbt/gold/distribuicao_situacao_funcional.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/gold/distribuicao_situacao_funcional.sql rename to dbt/ipea/models/pessoas_dbt/gold/distribuicao_situacao_funcional.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/gold/hierarquia.sql b/dbt/ipea/models/pessoas_dbt/gold/hierarquia.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/gold/hierarquia.sql rename to dbt/ipea/models/pessoas_dbt/gold/hierarquia.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/gold/kpis_servidores.sql b/dbt/ipea/models/pessoas_dbt/gold/kpis_servidores.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/gold/kpis_servidores.sql rename to dbt/ipea/models/pessoas_dbt/gold/kpis_servidores.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/gold/resumo_quadro_pessoal.sql b/dbt/ipea/models/pessoas_dbt/gold/resumo_quadro_pessoal.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/gold/resumo_quadro_pessoal.sql rename to dbt/ipea/models/pessoas_dbt/gold/resumo_quadro_pessoal.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/gold/schema.yml b/dbt/ipea/models/pessoas_dbt/gold/schema.yml similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/gold/schema.yml rename to dbt/ipea/models/pessoas_dbt/gold/schema.yml diff --git a/airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/gold/tabela_servidores_agregada.sql b/dbt/ipea/models/pessoas_dbt/gold/tabela_servidores_agregada.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/gold/tabela_servidores_agregada.sql rename to dbt/ipea/models/pessoas_dbt/gold/tabela_servidores_agregada.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/silver/afastamento_consolidado.sql b/dbt/ipea/models/pessoas_dbt/silver/afastamento_consolidado.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/silver/afastamento_consolidado.sql rename to dbt/ipea/models/pessoas_dbt/silver/afastamento_consolidado.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/silver/quantitativo_alocados_ocupados.sql b/dbt/ipea/models/pessoas_dbt/silver/quantitativo_alocados_ocupados.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/silver/quantitativo_alocados_ocupados.sql rename to dbt/ipea/models/pessoas_dbt/silver/quantitativo_alocados_ocupados.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/silver/schema.yml b/dbt/ipea/models/pessoas_dbt/silver/schema.yml similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/silver/schema.yml rename to dbt/ipea/models/pessoas_dbt/silver/schema.yml diff --git a/airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/silver/servidores_completos.sql b/dbt/ipea/models/pessoas_dbt/silver/servidores_completos.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/silver/servidores_completos.sql rename to dbt/ipea/models/pessoas_dbt/silver/servidores_completos.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/silver/servidores_detalhados.sql b/dbt/ipea/models/pessoas_dbt/silver/servidores_detalhados.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/silver/servidores_detalhados.sql rename to dbt/ipea/models/pessoas_dbt/silver/servidores_detalhados.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/silver/tabela_correlacao_cargos.sql b/dbt/ipea/models/pessoas_dbt/silver/tabela_correlacao_cargos.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/silver/tabela_correlacao_cargos.sql rename to dbt/ipea/models/pessoas_dbt/silver/tabela_correlacao_cargos.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/silver/unidades_organizacionais_siorg_siape.sql b/dbt/ipea/models/pessoas_dbt/silver/unidades_organizacionais_siorg_siape.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/pessoas_dbt/silver/unidades_organizacionais_siorg_siape.sql rename to dbt/ipea/models/pessoas_dbt/silver/unidades_organizacionais_siorg_siape.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/sources.yml b/dbt/ipea/models/sources.yml similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/sources.yml rename to dbt/ipea/models/sources.yml diff --git a/airflow_lappis/dags/dbt/ipea/models/ted_dbt/bronze/nc_tesouro.sql b/dbt/ipea/models/ted_dbt/bronze/nc_tesouro.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/ted_dbt/bronze/nc_tesouro.sql rename to dbt/ipea/models/ted_dbt/bronze/nc_tesouro.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/ted_dbt/bronze/pf_tesouro.sql b/dbt/ipea/models/ted_dbt/bronze/pf_tesouro.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/ted_dbt/bronze/pf_tesouro.sql rename to dbt/ipea/models/ted_dbt/bronze/pf_tesouro.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/ted_dbt/bronze/planos_acao.sql b/dbt/ipea/models/ted_dbt/bronze/planos_acao.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/ted_dbt/bronze/planos_acao.sql rename to dbt/ipea/models/ted_dbt/bronze/planos_acao.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/ted_dbt/bronze/schema.yml b/dbt/ipea/models/ted_dbt/bronze/schema.yml similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/ted_dbt/bronze/schema.yml rename to dbt/ipea/models/ted_dbt/bronze/schema.yml diff --git a/airflow_lappis/dags/dbt/ipea/models/ted_dbt/gold/schema.yml b/dbt/ipea/models/ted_dbt/gold/schema.yml similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/ted_dbt/gold/schema.yml rename to dbt/ipea/models/ted_dbt/gold/schema.yml diff --git a/airflow_lappis/dags/dbt/ipea/models/ted_dbt/gold/ted_resumo_orcamentario.sql b/dbt/ipea/models/ted_dbt/gold/ted_resumo_orcamentario.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/ted_dbt/gold/ted_resumo_orcamentario.sql rename to dbt/ipea/models/ted_dbt/gold/ted_resumo_orcamentario.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/ted_dbt/silver/empenhos_plano_acao.sql b/dbt/ipea/models/ted_dbt/silver/empenhos_plano_acao.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/ted_dbt/silver/empenhos_plano_acao.sql rename to dbt/ipea/models/ted_dbt/silver/empenhos_plano_acao.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/ted_dbt/silver/nc_plano_acao.sql b/dbt/ipea/models/ted_dbt/silver/nc_plano_acao.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/ted_dbt/silver/nc_plano_acao.sql rename to dbt/ipea/models/ted_dbt/silver/nc_plano_acao.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/ted_dbt/silver/pf_plano_acao.sql b/dbt/ipea/models/ted_dbt/silver/pf_plano_acao.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/ted_dbt/silver/pf_plano_acao.sql rename to dbt/ipea/models/ted_dbt/silver/pf_plano_acao.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/ted_dbt/silver/schema.yml b/dbt/ipea/models/ted_dbt/silver/schema.yml similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/ted_dbt/silver/schema.yml rename to dbt/ipea/models/ted_dbt/silver/schema.yml diff --git a/airflow_lappis/dags/dbt/ipea/models/ted_dbt/views/num_transf_n_plano_acao.sql b/dbt/ipea/models/ted_dbt/views/num_transf_n_plano_acao.sql similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/ted_dbt/views/num_transf_n_plano_acao.sql rename to dbt/ipea/models/ted_dbt/views/num_transf_n_plano_acao.sql diff --git a/airflow_lappis/dags/dbt/ipea/models/ted_dbt/views/schema.yml b/dbt/ipea/models/ted_dbt/views/schema.yml similarity index 100% rename from airflow_lappis/dags/dbt/ipea/models/ted_dbt/views/schema.yml rename to dbt/ipea/models/ted_dbt/views/schema.yml diff --git a/airflow_lappis/dags/dbt/ipea/profiles.yml b/dbt/ipea/profiles.yml similarity index 100% rename from airflow_lappis/dags/dbt/ipea/profiles.yml rename to dbt/ipea/profiles.yml diff --git a/airflow_lappis/dags/dbt/ipea/seeds/estados_brasil.csv b/dbt/ipea/seeds/estados_brasil.csv similarity index 100% rename from airflow_lappis/dags/dbt/ipea/seeds/estados_brasil.csv rename to dbt/ipea/seeds/estados_brasil.csv diff --git a/airflow_lappis/dags/dbt/ipea/snapshots/tables_snapshot.yml b/dbt/ipea/snapshots/tables_snapshot.yml similarity index 100% rename from airflow_lappis/dags/dbt/ipea/snapshots/tables_snapshot.yml rename to dbt/ipea/snapshots/tables_snapshot.yml diff --git a/airflow_lappis/dags/dbt/mir/.user.yml b/dbt/mir/.user.yml similarity index 100% rename from airflow_lappis/dags/dbt/mir/.user.yml rename to dbt/mir/.user.yml diff --git a/airflow_lappis/dags/dbt/mir/dbt_project.yml b/dbt/mir/dbt_project.yml similarity index 100% rename from airflow_lappis/dags/dbt/mir/dbt_project.yml rename to dbt/mir/dbt_project.yml diff --git a/airflow_lappis/dags/dbt/mir/descriptions.yml b/dbt/mir/descriptions.yml similarity index 100% rename from airflow_lappis/dags/dbt/mir/descriptions.yml rename to dbt/mir/descriptions.yml diff --git a/airflow_lappis/dags/dbt/mir/macros/create_udfs.sql b/dbt/mir/macros/create_udfs.sql similarity index 100% rename from airflow_lappis/dags/dbt/mir/macros/create_udfs.sql rename to dbt/mir/macros/create_udfs.sql diff --git a/airflow_lappis/dags/dbt/mir/macros/data_quality/row_count_match.sql b/dbt/mir/macros/data_quality/row_count_match.sql similarity index 100% rename from airflow_lappis/dags/dbt/mir/macros/data_quality/row_count_match.sql rename to dbt/mir/macros/data_quality/row_count_match.sql diff --git a/airflow_lappis/dags/dbt/mir/macros/data_quality/verificacao_tipagem.sql b/dbt/mir/macros/data_quality/verificacao_tipagem.sql similarity index 100% rename from airflow_lappis/dags/dbt/mir/macros/data_quality/verificacao_tipagem.sql rename to dbt/mir/macros/data_quality/verificacao_tipagem.sql diff --git a/airflow_lappis/dags/dbt/mir/macros/get_custom_schema.sql b/dbt/mir/macros/get_custom_schema.sql similarity index 100% rename from airflow_lappis/dags/dbt/mir/macros/get_custom_schema.sql rename to dbt/mir/macros/get_custom_schema.sql diff --git a/airflow_lappis/dags/dbt/mir/macros/metadata/generate_metadata.sql b/dbt/mir/macros/metadata/generate_metadata.sql similarity index 100% rename from airflow_lappis/dags/dbt/mir/macros/metadata/generate_metadata.sql rename to dbt/mir/macros/metadata/generate_metadata.sql diff --git a/airflow_lappis/dags/dbt/mir/macros/parse_financial_value.sql b/dbt/mir/macros/parse_financial_value.sql similarity index 100% rename from airflow_lappis/dags/dbt/mir/macros/parse_financial_value.sql rename to dbt/mir/macros/parse_financial_value.sql diff --git a/airflow_lappis/dags/dbt/mir/macros/schema.yml b/dbt/mir/macros/schema.yml similarity index 100% rename from airflow_lappis/dags/dbt/mir/macros/schema.yml rename to dbt/mir/macros/schema.yml diff --git a/airflow_lappis/dags/dbt/mir/macros/udfs/f_format_nc.sql b/dbt/mir/macros/udfs/f_format_nc.sql similarity index 100% rename from airflow_lappis/dags/dbt/mir/macros/udfs/f_format_nc.sql rename to dbt/mir/macros/udfs/f_format_nc.sql diff --git a/airflow_lappis/dags/dbt/mir/macros/udfs/f_parse_dates.sql b/dbt/mir/macros/udfs/f_parse_dates.sql similarity index 100% rename from airflow_lappis/dags/dbt/mir/macros/udfs/f_parse_dates.sql rename to dbt/mir/macros/udfs/f_parse_dates.sql diff --git a/airflow_lappis/dags/dbt/mir/models/dados_abertos_dbt/bronze/deputados.sql b/dbt/mir/models/dados_abertos_dbt/bronze/deputados.sql similarity index 100% rename from airflow_lappis/dags/dbt/mir/models/dados_abertos_dbt/bronze/deputados.sql rename to dbt/mir/models/dados_abertos_dbt/bronze/deputados.sql diff --git a/airflow_lappis/dags/dbt/mir/models/dados_abertos_dbt/bronze/schema.yml b/dbt/mir/models/dados_abertos_dbt/bronze/schema.yml similarity index 100% rename from airflow_lappis/dags/dbt/mir/models/dados_abertos_dbt/bronze/schema.yml rename to dbt/mir/models/dados_abertos_dbt/bronze/schema.yml diff --git a/airflow_lappis/dags/dbt/mir/models/dados_abertos_dbt/bronze/senadores.sql b/dbt/mir/models/dados_abertos_dbt/bronze/senadores.sql similarity index 100% rename from airflow_lappis/dags/dbt/mir/models/dados_abertos_dbt/bronze/senadores.sql rename to dbt/mir/models/dados_abertos_dbt/bronze/senadores.sql diff --git a/airflow_lappis/dags/dbt/mir/models/dados_abertos_dbt/silver/parlamentares.sql b/dbt/mir/models/dados_abertos_dbt/silver/parlamentares.sql similarity index 100% rename from airflow_lappis/dags/dbt/mir/models/dados_abertos_dbt/silver/parlamentares.sql rename to dbt/mir/models/dados_abertos_dbt/silver/parlamentares.sql diff --git a/airflow_lappis/dags/dbt/mir/models/dados_abertos_dbt/silver/schema.yml b/dbt/mir/models/dados_abertos_dbt/silver/schema.yml similarity index 100% rename from airflow_lappis/dags/dbt/mir/models/dados_abertos_dbt/silver/schema.yml rename to dbt/mir/models/dados_abertos_dbt/silver/schema.yml diff --git a/airflow_lappis/dags/dbt/mir/models/emendas_dbt/bronze/documentos_habeis.sql b/dbt/mir/models/emendas_dbt/bronze/documentos_habeis.sql similarity index 100% rename from airflow_lappis/dags/dbt/mir/models/emendas_dbt/bronze/documentos_habeis.sql rename to dbt/mir/models/emendas_dbt/bronze/documentos_habeis.sql diff --git a/airflow_lappis/dags/dbt/mir/models/emendas_dbt/bronze/empenhos_especiais.sql b/dbt/mir/models/emendas_dbt/bronze/empenhos_especiais.sql similarity index 100% rename from airflow_lappis/dags/dbt/mir/models/emendas_dbt/bronze/empenhos_especiais.sql rename to dbt/mir/models/emendas_dbt/bronze/empenhos_especiais.sql diff --git a/airflow_lappis/dags/dbt/mir/models/emendas_dbt/bronze/executor.sql b/dbt/mir/models/emendas_dbt/bronze/executor.sql similarity index 100% rename from airflow_lappis/dags/dbt/mir/models/emendas_dbt/bronze/executor.sql rename to dbt/mir/models/emendas_dbt/bronze/executor.sql diff --git a/airflow_lappis/dags/dbt/mir/models/emendas_dbt/bronze/finalidades.sql b/dbt/mir/models/emendas_dbt/bronze/finalidades.sql similarity index 100% rename from airflow_lappis/dags/dbt/mir/models/emendas_dbt/bronze/finalidades.sql rename to dbt/mir/models/emendas_dbt/bronze/finalidades.sql diff --git a/airflow_lappis/dags/dbt/mir/models/emendas_dbt/bronze/historico_pagamentos.sql b/dbt/mir/models/emendas_dbt/bronze/historico_pagamentos.sql similarity index 100% rename from airflow_lappis/dags/dbt/mir/models/emendas_dbt/bronze/historico_pagamentos.sql rename to dbt/mir/models/emendas_dbt/bronze/historico_pagamentos.sql diff --git a/airflow_lappis/dags/dbt/mir/models/emendas_dbt/bronze/metas.sql b/dbt/mir/models/emendas_dbt/bronze/metas.sql similarity index 100% rename from airflow_lappis/dags/dbt/mir/models/emendas_dbt/bronze/metas.sql rename to dbt/mir/models/emendas_dbt/bronze/metas.sql diff --git a/airflow_lappis/dags/dbt/mir/models/emendas_dbt/bronze/ordens_bancarias.sql b/dbt/mir/models/emendas_dbt/bronze/ordens_bancarias.sql similarity index 100% rename from airflow_lappis/dags/dbt/mir/models/emendas_dbt/bronze/ordens_bancarias.sql rename to dbt/mir/models/emendas_dbt/bronze/ordens_bancarias.sql diff --git a/airflow_lappis/dags/dbt/mir/models/emendas_dbt/bronze/planos_acoes.sql b/dbt/mir/models/emendas_dbt/bronze/planos_acoes.sql similarity index 100% rename from airflow_lappis/dags/dbt/mir/models/emendas_dbt/bronze/planos_acoes.sql rename to dbt/mir/models/emendas_dbt/bronze/planos_acoes.sql diff --git a/airflow_lappis/dags/dbt/mir/models/emendas_dbt/bronze/planos_trabalho_especial.sql b/dbt/mir/models/emendas_dbt/bronze/planos_trabalho_especial.sql similarity index 100% rename from airflow_lappis/dags/dbt/mir/models/emendas_dbt/bronze/planos_trabalho_especial.sql rename to dbt/mir/models/emendas_dbt/bronze/planos_trabalho_especial.sql diff --git a/airflow_lappis/dags/dbt/mir/models/emendas_dbt/bronze/programas.sql b/dbt/mir/models/emendas_dbt/bronze/programas.sql similarity index 100% rename from airflow_lappis/dags/dbt/mir/models/emendas_dbt/bronze/programas.sql rename to dbt/mir/models/emendas_dbt/bronze/programas.sql diff --git a/airflow_lappis/dags/dbt/mir/models/emendas_dbt/bronze/relatorio_gestao.sql b/dbt/mir/models/emendas_dbt/bronze/relatorio_gestao.sql similarity index 100% rename from airflow_lappis/dags/dbt/mir/models/emendas_dbt/bronze/relatorio_gestao.sql rename to dbt/mir/models/emendas_dbt/bronze/relatorio_gestao.sql diff --git a/airflow_lappis/dags/dbt/mir/models/emendas_dbt/bronze/relatorio_gestao_novo.sql b/dbt/mir/models/emendas_dbt/bronze/relatorio_gestao_novo.sql similarity index 100% rename from airflow_lappis/dags/dbt/mir/models/emendas_dbt/bronze/relatorio_gestao_novo.sql rename to dbt/mir/models/emendas_dbt/bronze/relatorio_gestao_novo.sql diff --git a/airflow_lappis/dags/dbt/mir/models/emendas_dbt/bronze/schema.yml b/dbt/mir/models/emendas_dbt/bronze/schema.yml similarity index 100% rename from airflow_lappis/dags/dbt/mir/models/emendas_dbt/bronze/schema.yml rename to dbt/mir/models/emendas_dbt/bronze/schema.yml diff --git a/airflow_lappis/dags/dbt/mir/models/emendas_dbt/bronze/tg_emendas.sql b/dbt/mir/models/emendas_dbt/bronze/tg_emendas.sql similarity index 100% rename from airflow_lappis/dags/dbt/mir/models/emendas_dbt/bronze/tg_emendas.sql rename to dbt/mir/models/emendas_dbt/bronze/tg_emendas.sql diff --git a/airflow_lappis/dags/dbt/mir/models/emendas_dbt/silver/planos_partidos.sql b/dbt/mir/models/emendas_dbt/silver/planos_partidos.sql similarity index 100% rename from airflow_lappis/dags/dbt/mir/models/emendas_dbt/silver/planos_partidos.sql rename to dbt/mir/models/emendas_dbt/silver/planos_partidos.sql diff --git a/airflow_lappis/dags/dbt/mir/models/emendas_dbt/silver/schema.yml b/dbt/mir/models/emendas_dbt/silver/schema.yml similarity index 100% rename from airflow_lappis/dags/dbt/mir/models/emendas_dbt/silver/schema.yml rename to dbt/mir/models/emendas_dbt/silver/schema.yml diff --git a/airflow_lappis/dags/dbt/mir/models/empenhos_ted_dbt/bronze/empenhos_tesouro_ted.sql b/dbt/mir/models/empenhos_ted_dbt/bronze/empenhos_tesouro_ted.sql similarity index 100% rename from airflow_lappis/dags/dbt/mir/models/empenhos_ted_dbt/bronze/empenhos_tesouro_ted.sql rename to dbt/mir/models/empenhos_ted_dbt/bronze/empenhos_tesouro_ted.sql diff --git a/airflow_lappis/dags/dbt/mir/models/empenhos_ted_dbt/bronze/schema.yaml b/dbt/mir/models/empenhos_ted_dbt/bronze/schema.yaml similarity index 100% rename from airflow_lappis/dags/dbt/mir/models/empenhos_ted_dbt/bronze/schema.yaml rename to dbt/mir/models/empenhos_ted_dbt/bronze/schema.yaml diff --git a/airflow_lappis/dags/dbt/mir/models/metadata/models_metadata.sql b/dbt/mir/models/metadata/models_metadata.sql similarity index 100% rename from airflow_lappis/dags/dbt/mir/models/metadata/models_metadata.sql rename to dbt/mir/models/metadata/models_metadata.sql diff --git a/airflow_lappis/dags/dbt/mir/models/metadata/schema.yml b/dbt/mir/models/metadata/schema.yml similarity index 100% rename from airflow_lappis/dags/dbt/mir/models/metadata/schema.yml rename to dbt/mir/models/metadata/schema.yml diff --git a/airflow_lappis/dags/dbt/mir/models/sources.yml b/dbt/mir/models/sources.yml similarity index 100% rename from airflow_lappis/dags/dbt/mir/models/sources.yml rename to dbt/mir/models/sources.yml diff --git a/airflow_lappis/dags/dbt/mir/profiles.yml b/dbt/mir/profiles.yml similarity index 100% rename from airflow_lappis/dags/dbt/mir/profiles.yml rename to dbt/mir/profiles.yml diff --git a/airflow_lappis/dags/dbt/mir/seeds/partidos_logo.csv b/dbt/mir/seeds/partidos_logo.csv similarity index 100% rename from airflow_lappis/dags/dbt/mir/seeds/partidos_logo.csv rename to dbt/mir/seeds/partidos_logo.csv diff --git a/airflow_lappis/dags/dbt/mir/seeds/partidos_map.csv b/dbt/mir/seeds/partidos_map.csv similarity index 100% rename from airflow_lappis/dags/dbt/mir/seeds/partidos_map.csv rename to dbt/mir/seeds/partidos_map.csv diff --git a/airflow_lappis/dags/dbt/mir/seeds/schema.yml b/dbt/mir/seeds/schema.yml similarity index 100% rename from airflow_lappis/dags/dbt/mir/seeds/schema.yml rename to dbt/mir/seeds/schema.yml diff --git a/airflow_lappis/dags/dbt/mir/tests/test_parlamentares_logo_partido.sql b/dbt/mir/tests/test_parlamentares_logo_partido.sql similarity index 100% rename from airflow_lappis/dags/dbt/mir/tests/test_parlamentares_logo_partido.sql rename to dbt/mir/tests/test_parlamentares_logo_partido.sql diff --git a/airflow_lappis/helpers/dados_funcionais_handler.py b/helpers/dados_funcionais_handler.py similarity index 100% rename from airflow_lappis/helpers/dados_funcionais_handler.py rename to helpers/dados_funcionais_handler.py diff --git a/airflow_lappis/helpers/postgres_helpers.py b/helpers/postgres_helpers.py similarity index 100% rename from airflow_lappis/helpers/postgres_helpers.py rename to helpers/postgres_helpers.py diff --git a/airflow_lappis/helpers/retry_helpers.py b/helpers/retry_helpers.py similarity index 100% rename from airflow_lappis/helpers/retry_helpers.py rename to helpers/retry_helpers.py diff --git a/airflow_lappis/helpers/safe_request.py b/helpers/safe_request.py similarity index 100% rename from airflow_lappis/helpers/safe_request.py rename to helpers/safe_request.py diff --git a/infra/README.md b/infra/README.md new file mode 100644 index 00000000..171ec89a --- /dev/null +++ b/infra/README.md @@ -0,0 +1,33 @@ +# Infra + +Arquivos de execucao local do projeto. + +## Compose + +Use os atalhos da raiz: + +```bash +make compose-config +make up +make logs-airflow +make down +``` + +Ou chame o Compose diretamente: + +```bash +docker compose -f infra/docker-compose.yml up postgres airflow airflow-mcp +``` + +## Layout + +```text +infra/ +├── airflow/ # airflow.cfg usado no ambiente local +├── docker/ +│ ├── airflow/ # imagem principal do Airflow +│ ├── airflow-mcp/ # imagem leve do MCP +│ └── postgres/ # scripts de init do Postgres +├── env/ # exemplos de variaveis de ambiente +└── docker-compose.yml +``` diff --git a/docker-compose.yml b/infra/docker-compose.yml similarity index 56% rename from docker-compose.yml rename to infra/docker-compose.yml index c346303c..2336e43f 100644 --- a/docker-compose.yml +++ b/infra/docker-compose.yml @@ -1,15 +1,25 @@ +name: data-application-minc + # Base configuration for Airflow services x-airflow-common: &airflow-common - build: . + build: + context: .. + dockerfile: infra/docker/airflow/Dockerfile + target: ${AIRFLOW_BUILD_TARGET:-airflow-dev} + args: + AIRFLOW_VERSION: ${AIRFLOW_VERSION:-2.8.1} + PYTHON_VERSION: ${PYTHON_VERSION:-3.11} user: "${AIRFLOW_UID:-50000}:0" env_file: - - .env + - ../.env volumes: - - ./airflow_lappis/airflow.cfg:${AIRFLOW_HOME}/airflow.cfg - - ./airflow_lappis/dags:${AIRFLOW_HOME}/dags/ - - ./airflow_lappis/plugins:${AIRFLOW_HOME}/plugins/ - - ./airflow_lappis/helpers:${AIRFLOW_HOME}/helpers/ - - ./airflow_lappis/dags/dbt/ipea/profiles.yml:${AIRFLOW_HOME}/.dbt/profiles.yml + - ./airflow/airflow.cfg:/opt/airflow/airflow.cfg + - ../dags:/opt/airflow/dags/ + - ../plugins:/opt/airflow/plugins/ + - ../helpers:/opt/airflow/helpers/ + - ../templates:/opt/airflow/templates/ + - ../dbt:/opt/airflow/dbt/ + - ../dbt/ipea/profiles.yml:/opt/airflow/.dbt/profiles.yml depends_on: &airflow-common-depends-on postgres: condition: service_healthy @@ -19,12 +29,12 @@ x-airflow-environment: &airflow-common-env AIRFLOW__CORE__DEFAULT_TIMEZONE: 'America/Sao_Paulo' AIRFLOW__CORE__ENABLE_XCOM_PICKLING: 'true' AIRFLOW__CORE__EXECUTOR: LocalExecutor - AIRFLOW__CORE__FERNET_KEY: ${AIRFLOW__CORE__FERNET_KEY} + AIRFLOW__CORE__FERNET_KEY: ${AIRFLOW__CORE__FERNET_KEY:-} AIRFLOW__CORE__LOAD_EXAMPLES: 'false' AIRFLOW__CORE__TEST_CONNECTION: Enabled AIRFLOW__CORE__MAX_MAP_LENGTH: 15000 AIRFLOW__API__AUTH_BACKENDS: airflow.api.auth.backend.basic_auth - AIRFLOW__DATABASE__SQL_ALCHEMY_CONN: postgresql+psycopg2://${POSTGRES_USER:-airflow}:${POSTGRES_PASSWORD:-airflow}@postgres/airflow + AIRFLOW__DATABASE__SQL_ALCHEMY_CONN: postgresql+psycopg2://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@postgres/airflow AIRFLOW__EMAIL__DEFAULT_EMAIL_ON_RETRY: 'false' AIRFLOW__EMAIL__DEFAULT_EMAIL_ON_FAILURE: 'false' AIRFLOW__WEBSERVER__DEFAULT_UI_TIMEZONE: 'America/Sao_Paulo' @@ -32,14 +42,14 @@ x-airflow-environment: &airflow-common-env AIRFLOW__WEBSERVER__NAVBAR_COLOR: '#98DFFF' AIRFLOW__WEBSERVER__RELOAD_ON_PLUGIN_CHANGE: 'true' AIRFLOW__WEBSERVER__SECRET_KEY: '42' - PYTHONPATH: "/opt/airflow/dags:/opt/airflow/plugins:/opt/airflow/helpers:$PYTHONPATH" + PYTHONPATH: "/opt/airflow/dags:/opt/airflow/plugins:/opt/airflow/helpers" _AIRFLOW_DB_MIGRATE: 'true' _AIRFLOW_WWW_USER_CREATE: 'true' _AIRFLOW_WWW_USER_USERNAME: ${_AIRFLOW_WWW_USER_USERNAME:-airflow} _AIRFLOW_WWW_USER_PASSWORD: ${_AIRFLOW_WWW_USER_PASSWORD:-airflow} - AIRFLOW__CORE__PLUGINS_FOLDER: ${AIRFLOW_HOME}/plugins - AIRFLOW__CORE__DAGS_FOLDER: ${AIRFLOW_HOME}/dags - AIRFLOW_REPO_BASE: ${AIRFLOW_HOME} + AIRFLOW__CORE__PLUGINS_FOLDER: /opt/airflow/plugins + AIRFLOW__CORE__DAGS_FOLDER: /opt/airflow/dags + AIRFLOW_REPO_BASE: /opt/airflow # A ENV AIRFLOW_REPO_BASE É IMPORTANTE PARA SINCRONIZAR COM O SISTEMA DE PASTAS # DO AIRFLOW EM HOMOLOG E PROD, ELES POSSUEM UMA ESTRUTURA DE PASTAS DIFERENTE # USAR ESSA ENV NOS CÓDIGOS PARA NÃO HAVER CONFLITOS @@ -68,67 +78,43 @@ services: postgres: image: postgres:15-alpine env_file: - - .env + - ../.env environment: - POSTGRES_DB: ${POSTGRES_DB} - POSTGRES_USER: ${POSTGRES_USER} - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + POSTGRES_DB: ${POSTGRES_DB:-postgres} + POSTGRES_USER: ${POSTGRES_USER:-postgres} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres} volumes: - postgres-db:/var/lib/postgresql/data - ./docker/postgres/:/docker-entrypoint-initdb.d/ ports: - "5432:5432" healthcheck: - test: ["CMD-SHELL", "pg_isready -U $POSTGRES_USER"] + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres}"] interval: 10s timeout: 5s retries: 5 restart: always - # Analytics Tools - superset: + airflow-mcp: build: - context: . - dockerfile: Dockerfile.superset # Custom Dockerfile with PostgreSQL drivers + context: .. + dockerfile: infra/docker/airflow-mcp/Dockerfile + profiles: + - dev environment: - SUPERSET_SECRET_KEY: 'supersetadmin' - SUPERSET_ENV: development - DATABASE_URL: postgresql+psycopg2://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/superset + AIRFLOW_API_URL: http://airflow:8080 + AIRFLOW_USERNAME: ${_AIRFLOW_WWW_USER_USERNAME:-airflow} + AIRFLOW_PASSWORD: ${_AIRFLOW_WWW_USER_PASSWORD:-airflow} + AF_READ_ONLY: ${AF_READ_ONLY:-false} + MCP_TRANSPORT: http + MCP_HOST: 0.0.0.0 + MCP_PORT: 8000 ports: - - "8088:8088" + - "127.0.0.1:8000:8000" depends_on: - - postgres - restart: always - healthcheck: - test: ["CMD", "curl", "--fail", "http://localhost:8088/health"] - interval: 30s - timeout: 10s - retries: 3 - command: > - /bin/sh -c " - superset fab create-admin --username admin --firstname Admin --lastname User --email admin@superset.com --password admin && - superset db upgrade && - superset init && - superset run -p 8088 -h 0.0.0.0 --with-threads --reload --debugger - " - - jupyter: - image: jupyter/base-notebook:latest - command: > - jupyter lab - --ip=0.0.0.0 - --no-browser - --allow-root - --NotebookApp.token='' - --NotebookApp.password='' - ports: - - "8888:8888" - volumes: - - ./notebooks:/home/jovyan/notebooks - environment: - JUPYTER_ENABLE_LAB: "yes" + airflow: + condition: service_healthy restart: always volumes: postgres-db: - airflow_logs: \ No newline at end of file diff --git a/infra/docker/airflow-mcp/Dockerfile b/infra/docker/airflow-mcp/Dockerfile new file mode 100644 index 00000000..a4c4cd6e --- /dev/null +++ b/infra/docker/airflow-mcp/Dockerfile @@ -0,0 +1,11 @@ +FROM python:3.11-slim + +WORKDIR /app + +RUN pip install --no-cache-dir uv + +ENV PYTHONUNBUFFERED=1 + +EXPOSE 8000 + +CMD ["uvx", "astro-airflow-mcp", "--transport", "http", "--host", "0.0.0.0", "--port", "8000"] \ No newline at end of file diff --git a/infra/docker/airflow/Dockerfile b/infra/docker/airflow/Dockerfile new file mode 100644 index 00000000..259fc88d --- /dev/null +++ b/infra/docker/airflow/Dockerfile @@ -0,0 +1,64 @@ +ARG AIRFLOW_VERSION=2.8.1 +ARG PYTHON_VERSION=3.11 + +FROM apache/airflow:${AIRFLOW_VERSION}-python${PYTHON_VERSION} AS airflow-base + +USER root + +ENV AIRFLOW__CORE__LOAD_EXAMPLES=False \ + LANG=en_US.UTF-8 \ + LC_ALL=en_US.UTF-8 \ + PIP_DEFAULT_TIMEOUT=300 + +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + build-essential \ + curl \ + git \ + libgdal-dev \ + libgtk2.0-dev \ + libpq-dev \ + unzip \ + unixodbc-dev \ + vim \ + && sed -i "s,^\(MinProtocol[ ]*=\).*,\1TLSv1.0,g" /etc/ssl/openssl.cnf \ + && sed -i "s,^\(CipherString[ ]*=\).*,\1DEFAULT@SECLEVEL=1,g" /etc/ssl/openssl.cnf \ + && curl -fsSLo /usr/local/share/ca-certificates/ACcompactado.zip http://acraiz.icpbrasil.gov.br/credenciadas/CertificadosAC-ICP-Brasil/ACcompactado.zip \ + && unzip -o /usr/local/share/ca-certificates/ACcompactado.zip -d /usr/local/share/ca-certificates/ \ + && rm -f /usr/local/share/ca-certificates/ACcompactado.zip \ + && update-ca-certificates \ + && sed -i 's/^# en_US.UTF-8 UTF-8$/en_US.UTF-8 UTF-8/g' /etc/locale.gen \ + && sed -i 's/^# pt_BR.UTF-8 UTF-8$/pt_BR.UTF-8 UTF-8/g' /etc/locale.gen \ + && locale-gen en_US.UTF-8 pt_BR.UTF-8 \ + && update-locale LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 \ + && apt-get autoremove -yqq --purge \ + && apt-get clean \ + && rm -rf \ + /var/lib/apt/lists/* \ + /var/cache/apt/* \ + /usr/share/doc \ + /usr/share/doc-base \ + /usr/share/man + +USER airflow +WORKDIR ${AIRFLOW_HOME} + + +FROM airflow-base AS airflow-prod + +COPY requirements.txt ./requirements.txt + +RUN python -m pip install --no-cache-dir -r requirements.txt \ + && rm -f requirements.txt + +ENV ENVIRONMENT=prod + + +FROM airflow-base AS airflow-dev + +COPY requirements.txt ./requirements.txt + +RUN python -m pip install --no-cache-dir -r requirements.txt \ + && rm -f requirements.txt + +ENV ENVIRONMENT=dev diff --git a/docker/postgres/init.sh b/infra/docker/postgres/init.sh similarity index 86% rename from docker/postgres/init.sh rename to infra/docker/postgres/init.sh index f07c4124..df76792d 100755 --- a/docker/postgres/init.sh +++ b/infra/docker/postgres/init.sh @@ -3,6 +3,5 @@ set -e psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL CREATE DATABASE airflow; - CREATE DATABASE superset; CREATE DATABASE data_warehouse; EOSQL diff --git a/infra/env/.env.example b/infra/env/.env.example new file mode 100644 index 00000000..433bdbac --- /dev/null +++ b/infra/env/.env.example @@ -0,0 +1,15 @@ +AIRFLOW_UID=50000 +AIRFLOW_HOME=/opt/airflow +AIRFLOW_VERSION=2.8.1 +PYTHON_VERSION=3.11 +AIRFLOW_BUILD_TARGET=airflow-dev + +POSTGRES_DB=postgres +POSTGRES_USER=postgres +POSTGRES_PASSWORD=postgres + +AIRFLOW__CORE__FERNET_KEY= +_AIRFLOW_WWW_USER_USERNAME=airflow +_AIRFLOW_WWW_USER_PASSWORD=airflow + +AF_READ_ONLY=false diff --git a/airflow_lappis/plugins/cliente_base.py b/plugins/cliente_base.py similarity index 100% rename from airflow_lappis/plugins/cliente_base.py rename to plugins/cliente_base.py diff --git a/airflow_lappis/plugins/cliente_contratos.py b/plugins/cliente_contratos.py similarity index 100% rename from airflow_lappis/plugins/cliente_contratos.py rename to plugins/cliente_contratos.py diff --git a/airflow_lappis/plugins/cliente_deputados.py b/plugins/cliente_deputados.py similarity index 100% rename from airflow_lappis/plugins/cliente_deputados.py rename to plugins/cliente_deputados.py diff --git a/airflow_lappis/plugins/cliente_email.py b/plugins/cliente_email.py similarity index 100% rename from airflow_lappis/plugins/cliente_email.py rename to plugins/cliente_email.py diff --git a/airflow_lappis/plugins/cliente_github.py b/plugins/cliente_github.py similarity index 100% rename from airflow_lappis/plugins/cliente_github.py rename to plugins/cliente_github.py diff --git a/airflow_lappis/plugins/cliente_pncp.py b/plugins/cliente_pncp.py similarity index 100% rename from airflow_lappis/plugins/cliente_pncp.py rename to plugins/cliente_pncp.py diff --git a/airflow_lappis/plugins/cliente_postgres.py b/plugins/cliente_postgres.py similarity index 100% rename from airflow_lappis/plugins/cliente_postgres.py rename to plugins/cliente_postgres.py diff --git a/airflow_lappis/plugins/cliente_senadores.py b/plugins/cliente_senadores.py similarity index 100% rename from airflow_lappis/plugins/cliente_senadores.py rename to plugins/cliente_senadores.py diff --git a/airflow_lappis/plugins/cliente_siafi.py b/plugins/cliente_siafi.py similarity index 100% rename from airflow_lappis/plugins/cliente_siafi.py rename to plugins/cliente_siafi.py diff --git a/airflow_lappis/plugins/cliente_siape.py b/plugins/cliente_siape.py similarity index 100% rename from airflow_lappis/plugins/cliente_siape.py rename to plugins/cliente_siape.py diff --git a/airflow_lappis/plugins/cliente_siorg.py b/plugins/cliente_siorg.py similarity index 100% rename from airflow_lappis/plugins/cliente_siorg.py rename to plugins/cliente_siorg.py diff --git a/airflow_lappis/plugins/cliente_ted.py b/plugins/cliente_ted.py similarity index 100% rename from airflow_lappis/plugins/cliente_ted.py rename to plugins/cliente_ted.py diff --git a/airflow_lappis/plugins/cliente_transferegov_emendas.py b/plugins/cliente_transferegov_emendas.py similarity index 100% rename from airflow_lappis/plugins/cliente_transferegov_emendas.py rename to plugins/cliente_transferegov_emendas.py diff --git a/airflow_lappis/plugins/cliente_transferegov_fundo_a_fundo.py b/plugins/cliente_transferegov_fundo_a_fundo.py similarity index 100% rename from airflow_lappis/plugins/cliente_transferegov_fundo_a_fundo.py rename to plugins/cliente_transferegov_fundo_a_fundo.py diff --git a/airflow_lappis/plugins/extracao_planilhas.py b/plugins/extracao_planilhas.py similarity index 100% rename from airflow_lappis/plugins/extracao_planilhas.py rename to plugins/extracao_planilhas.py diff --git a/airflow_lappis/plugins/schedule_loader.py b/plugins/schedule_loader.py similarity index 100% rename from airflow_lappis/plugins/schedule_loader.py rename to plugins/schedule_loader.py diff --git a/pyproject.toml b/pyproject.toml index 74d883aa..45682f5a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,7 +31,6 @@ mypy = "*" types-psycopg2 = "*" pandas-stubs = "*" sqlalchemy-stubs = "*" -jupyter = "*" shandy-sqlfmt = "*" sqlfluff = "*" sqlfluff-templater-dbt = "*" @@ -158,8 +157,8 @@ capitalisation_policy = "lower" unwrap_wrapped_queries = true [tool.sqlfluff.templater.dbt] -project_dir = "./airflow_lappis/dags/dbt/ipea" -profiles_dir = "./airflow_lappis/dags/dbt/ipea" +project_dir = "./dbt/ipea" +profiles_dir = "./dbt/ipea" profile = "ipea" target = "prod" defer_mode = true diff --git a/requirements.txt b/requirements.txt index 1a6a9f8f..b6e8cb78 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,6 +7,6 @@ zeep==4.3.1 openpyxl xlrd>=2.0.1 odfpy>=1.4.1 -pyxlsb -python-calamine -apache-airflow-providers-amazon +pyxlsb==1.0.10 +python-calamine==0.6.2 +apache-airflow-providers-amazon==8.16.0 diff --git a/superset/__init__.py b/superset/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/airflow_lappis/templates/siape/consultaDadosAfastamento.xml.j2 b/templates/siape/consultaDadosAfastamento.xml.j2 similarity index 100% rename from airflow_lappis/templates/siape/consultaDadosAfastamento.xml.j2 rename to templates/siape/consultaDadosAfastamento.xml.j2 diff --git a/airflow_lappis/templates/siape/consultaDadosAfastamentoHistorico.xml.j2 b/templates/siape/consultaDadosAfastamentoHistorico.xml.j2 similarity index 100% rename from airflow_lappis/templates/siape/consultaDadosAfastamentoHistorico.xml.j2 rename to templates/siape/consultaDadosAfastamentoHistorico.xml.j2 diff --git a/airflow_lappis/templates/siape/consultaDadosCurriculo.xml.j2 b/templates/siape/consultaDadosCurriculo.xml.j2 similarity index 100% rename from airflow_lappis/templates/siape/consultaDadosCurriculo.xml.j2 rename to templates/siape/consultaDadosCurriculo.xml.j2 diff --git a/airflow_lappis/templates/siape/consultaDadosDependentes.xml.j2 b/templates/siape/consultaDadosDependentes.xml.j2 similarity index 100% rename from airflow_lappis/templates/siape/consultaDadosDependentes.xml.j2 rename to templates/siape/consultaDadosDependentes.xml.j2 diff --git a/airflow_lappis/templates/siape/consultaDadosEscolares.xml.j2 b/templates/siape/consultaDadosEscolares.xml.j2 similarity index 100% rename from airflow_lappis/templates/siape/consultaDadosEscolares.xml.j2 rename to templates/siape/consultaDadosEscolares.xml.j2 diff --git a/airflow_lappis/templates/siape/consultaDadosFinanceiros.xml.j2 b/templates/siape/consultaDadosFinanceiros.xml.j2 similarity index 100% rename from airflow_lappis/templates/siape/consultaDadosFinanceiros.xml.j2 rename to templates/siape/consultaDadosFinanceiros.xml.j2 diff --git a/airflow_lappis/templates/siape/consultaDadosFuncionais.xml.j2 b/templates/siape/consultaDadosFuncionais.xml.j2 similarity index 100% rename from airflow_lappis/templates/siape/consultaDadosFuncionais.xml.j2 rename to templates/siape/consultaDadosFuncionais.xml.j2 diff --git a/airflow_lappis/templates/siape/consultaDadosPA.xml.j2 b/templates/siape/consultaDadosPA.xml.j2 similarity index 100% rename from airflow_lappis/templates/siape/consultaDadosPA.xml.j2 rename to templates/siape/consultaDadosPA.xml.j2 diff --git a/airflow_lappis/templates/siape/consultaDadosPessoais.xml.j2 b/templates/siape/consultaDadosPessoais.xml.j2 similarity index 100% rename from airflow_lappis/templates/siape/consultaDadosPessoais.xml.j2 rename to templates/siape/consultaDadosPessoais.xml.j2 diff --git a/airflow_lappis/templates/siape/consultaDadosUorg.xml.j2 b/templates/siape/consultaDadosUorg.xml.j2 similarity index 100% rename from airflow_lappis/templates/siape/consultaDadosUorg.xml.j2 rename to templates/siape/consultaDadosUorg.xml.j2 diff --git a/airflow_lappis/templates/siape/consultaPensoesInstituidas.xml.j2 b/templates/siape/consultaPensoesInstituidas.xml.j2 similarity index 100% rename from airflow_lappis/templates/siape/consultaPensoesInstituidas.xml.j2 rename to templates/siape/consultaPensoesInstituidas.xml.j2 diff --git a/airflow_lappis/templates/siape/listaInformacoesAposentadoria.xml.j2 b/templates/siape/listaInformacoesAposentadoria.xml.j2 similarity index 100% rename from airflow_lappis/templates/siape/listaInformacoesAposentadoria.xml.j2 rename to templates/siape/listaInformacoesAposentadoria.xml.j2 diff --git a/airflow_lappis/templates/siape/listaServidores.xml.j2 b/templates/siape/listaServidores.xml.j2 similarity index 100% rename from airflow_lappis/templates/siape/listaServidores.xml.j2 rename to templates/siape/listaServidores.xml.j2 diff --git a/airflow_lappis/templates/siape/listaUorgs.xml.j2 b/templates/siape/listaUorgs.xml.j2 similarity index 100% rename from airflow_lappis/templates/siape/listaUorgs.xml.j2 rename to templates/siape/listaUorgs.xml.j2 From 9e4fed2ab0628969037b183a552619cca4059b7f Mon Sep 17 00:00:00 2001 From: arthrok Date: Mon, 15 Jun 2026 10:59:23 -0300 Subject: [PATCH 2/4] =?UTF-8?q?refactor:=20adapta=20as=20dags=20pro=20bump?= =?UTF-8?q?=20de=20vers=C3=A3o=202.8.1=20->=203.2.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/main.yaml | 4 +- dags/dashboards/__init__.py | 3 - dags/dashboards/dashboard_servidores_dag.py | 168 --- .../contratos_inativos_ingest_dag.py | 72 -- .../compras_gov/contratos_ingest_dag.py | 78 -- .../compras_gov/cronograma_ingest_dag.py | 67 - .../compras_gov/empenhos_ingest_dag.py | 65 - .../compras_gov/faturas_ingest_dag.py | 64 - .../compras_gov/terceirizados_ingest_dag.py | 62 - .../dados_abertos/deputados_ingest_dag.py | 77 -- .../dados_abertos/senadores_ingest_dag.py | 73 -- .../pncp/itens_resultados_licitacoes.py | 157 --- dags/data_ingest/pncp/licitacoes_ingest.py | 129 -- .../sgac/projetos_sgac_ingest_dag.py | 203 --- .../siafi/nota_credito_siafi_ingest_dag.py | 59 - .../siafi/nota_empenho_siafi_ingest_dag.py | 93 -- ...programacao_financeira_siafi_ingest_dag.py | 50 - ..._afastamento_historico_siape_ingest_dag.py | 95 -- .../dados_afastamento_siape_ingest_dag.py | 87 -- .../siape/dados_curriculo_siape_ingest_dag.py | 85 -- .../dados_dependentes_siape_ingest_dag.py | 87 -- .../siape/dados_escolares_siape_ingest_dag.py | 86 -- .../siape/dados_financeiros_siape_dag.py | 86 -- .../dados_funcionais_siape_ingest_dag.py | 82 -- .../siape/dados_pa_siape_ingest_dag.py | 121 -- .../siape/dados_pessoais_siape_ingest_dag.py | 141 -- .../siape/dados_uorg_siape_ingest_dag.py | 84 -- .../lista_aposentadoria_siape_ingest_dag.py | 90 -- .../lista_servidores_siape_ingest_dag.py | 82 -- .../siape/lista_uorgs_siape_ingest_dag.py | 113 -- .../pensoes_instituidas_siape_ingest_dag.py | 108 -- .../siorg/cargos_funcao_ingest_dag.py | 58 - ...rutura_organizacional_cargos_ingest_dag.py | 67 - .../unidade_organizacional_ingest_dag.py | 82 -- .../empenhos_tesouro_emendas_ingest_dag.py | 197 --- .../empenhos_tesouro_ingest_dag.py | 154 --- ..._execucao_outras_fontes_mcid_ingest_dag.py | 183 --- ...mpenho_emendas_parlamentares_ingest_dag.py | 155 --- .../orcamento_mcid_por_acao_ingest_dag.py | 194 --- ...penhos_tesouro_parlamentares_ingest_dag.py | 158 --- .../nc_tesouro_ingest.dag.py | 240 ---- .../pf_tesouro_ingest_dag.py | 249 ---- .../visao_orcamentaria_ingest.py | 324 ----- .../mir/notas_de_credito_ingest_mir_dag.py | 51 - .../mir/plano_acao_ingest_mir_dag.py | 56 - .../mir/programa_financeira_ingest_mir_dag.py | 55 - .../mir/programas_ingest_mir_dag.py | 55 - .../notas_de_credito_ingest_dag.py | 53 - .../transfere_gov/plano_acao_ingest_dag.py | 58 - .../programa_beneficiario_ingest_dag.py | 57 - .../programacao_financeira_ingest_dag.py | 56 - .../transfere_gov/programas_ingest_dag.py | 88 -- .../documentos_habeis_especias_ingest_dag.py | 71 -- .../empenhos_especiais_ingest_dag.py | 67 - .../executor_especial_ingest_dag.py | 74 -- .../finalidade_especial_ingest_dag.py | 78 -- ...storico_pagamentos_especiais_ingest_dag.py | 72 -- .../metas_especiais_ingest_dag.py | 61 - .../ordem_bancaria_especial_ingest_dag.py | 70 - .../plano_trabalho_especial_ingest_dag.py | 67 - .../planos_acao_especiais_ingest_dag.py | 77 -- .../programas_especiais_ingest_dag.py | 67 - ...latorio_gestao_novo_especial_ingest_dag.py | 71 -- .../reltorio_gestao_ingest.py | 57 - .../api_anexos_relatorios_dag.py} | 34 +- .../api_planos_acao_dag.py} | 36 +- .../api_programas_dag.py | 30 +- .../api_relatorios_gestao_dag.py} | 34 +- .../download_anexos_dag.py} | 18 +- .../extracao_anexos_dag.py} | 72 +- ...{ipea_cosmos_dag.py => minc_cosmos_dag.py} | 19 +- dags/dbt/mir_cosmos_dag.py | 30 - dbt/ipea/.user.yml | 1 - dbt/ipea/dbt_project.yml | 56 - dbt/ipea/descriptions.yml | 61 - dbt/ipea/macros/create_udfs.sql | 10 - .../macros/data_quality/row_count_match.sql | 14 - .../data_quality/verificacao_tipagem.sql | 25 - dbt/ipea/macros/get_custom_schema.sql | 4 - .../macros/metadata/generate_metadata.sql | 46 - dbt/ipea/macros/parse_financial_value.sql | 21 - dbt/ipea/macros/schema.yml | 24 - dbt/ipea/macros/udfs/f_format_nc.sql | 19 - dbt/ipea/macros/udfs/f_parse_dates.sql | 44 - .../models/contratos_dbt/bronze/contratos.sql | 123 -- .../contratos_dbt/bronze/cronogramas.sql | 24 - .../models/contratos_dbt/bronze/empenhos.sql | 58 - .../contratos_dbt/bronze/empenhos_tesouro.sql | 49 - .../models/contratos_dbt/bronze/faturas.sql | 51 - .../models/contratos_dbt/bronze/schema.yml | 480 ------- .../gold/contratos_comparativo_mensal.sql | 45 - .../contratos_dbt/gold/contratos_resumo.sql | 53 - .../gold/contratos_somatorio.sql | 18 - dbt/ipea/models/contratos_dbt/gold/schema.yml | 148 --- .../silver/contratos_empenhos.sql | 210 --- .../silver/contratos_estagios.sql | 116 -- .../silver/contratos_faturas.sql | 53 - .../silver/cronogramas_faturas_mensal.sql | 80 -- .../contratos_dbt/silver/estagios_mensal.sql | 134 -- .../models/contratos_dbt/silver/schema.yml | 272 ---- .../contratos_dbt/views/identificadores.sql | 59 - .../views/preenchimento_meses.sql | 17 - .../models/contratos_dbt/views/schema.yml | 30 - dbt/ipea/models/metadata/models_metadata.sql | 67 - dbt/ipea/models/metadata/schema.yml | 46 - .../models/orcamento_dbt/bronze/schema.yml | 14 - .../bronze/visao_orcamentaria_total.sql | 47 - .../bronze/afastamento_historico.sql | 133 -- .../pessoas_dbt/bronze/cargos_funcoes.sql | 61 - .../pessoas_dbt/bronze/dados_afastamento.sql | 109 -- .../pessoas_dbt/bronze/dados_curriculo.sql | 45 - .../pessoas_dbt/bronze/dados_dependentes.sql | 53 - .../pessoas_dbt/bronze/dados_escolares.sql | 28 - .../pessoas_dbt/bronze/dados_financeiros.sql | 127 -- .../pessoas_dbt/bronze/dados_funcionais.sql | 87 -- .../models/pessoas_dbt/bronze/dados_pa.sql | 40 - .../pessoas_dbt/bronze/dados_pessoais.sql | 52 - .../models/pessoas_dbt/bronze/dados_uorg.sql | 46 - .../estrutura_organizacional_cargos.sql | 78 -- .../pessoas_dbt/bronze/lista_servidores.sql | 8 - .../models/pessoas_dbt/bronze/lista_uorgs.sql | 8 - dbt/ipea/models/pessoas_dbt/bronze/schema.yml | 906 ------------- .../pessoas_dbt/bronze/terceirizados.sql | 21 - .../bronze/unidade_organizacional.sql | 42 - .../gold/aposentadorias_resumo.sql | 34 - .../pessoas_dbt/gold/cargos_consolidado.sql | 33 - .../pessoas_dbt/gold/distribuicao_genero.sql | 9 - .../pessoas_dbt/gold/distribuicao_mapa_uf.sql | 38 - .../gold/distribuicao_raca_cor.sql | 5 - .../gold/distribuicao_situacao_funcional.sql | 34 - .../models/pessoas_dbt/gold/hierarquia.sql | 154 --- .../pessoas_dbt/gold/kpis_servidores.sql | 48 - .../gold/resumo_quadro_pessoal.sql | 9 - dbt/ipea/models/pessoas_dbt/gold/schema.yml | 364 ------ .../gold/tabela_servidores_agregada.sql | 61 - .../silver/afastamento_consolidado.sql | 120 -- .../silver/quantitativo_alocados_ocupados.sql | 108 -- dbt/ipea/models/pessoas_dbt/silver/schema.yml | 335 ----- .../silver/servidores_completos.sql | 101 -- .../silver/servidores_detalhados.sql | 159 --- .../silver/tabela_correlacao_cargos.sql | 187 --- .../unidades_organizacionais_siorg_siape.sql | 54 - dbt/ipea/models/sources.yml | 76 -- dbt/ipea/models/ted_dbt/bronze/nc_tesouro.sql | 31 - dbt/ipea/models/ted_dbt/bronze/pf_tesouro.sql | 32 - .../models/ted_dbt/bronze/planos_acao.sql | 36 - dbt/ipea/models/ted_dbt/bronze/schema.yml | 234 ---- dbt/ipea/models/ted_dbt/gold/schema.yml | 64 - .../ted_dbt/gold/ted_resumo_orcamentario.sql | 116 -- .../ted_dbt/silver/empenhos_plano_acao.sql | 35 - .../models/ted_dbt/silver/nc_plano_acao.sql | 37 - .../models/ted_dbt/silver/pf_plano_acao.sql | 74 -- dbt/ipea/models/ted_dbt/silver/schema.yml | 125 -- .../ted_dbt/views/num_transf_n_plano_acao.sql | 36 - dbt/ipea/models/ted_dbt/views/schema.yml | 16 - dbt/ipea/seeds/estados_brasil.csv | 28 - dbt/ipea/snapshots/tables_snapshot.yml | 36 - dbt/{mir => minc}/dbt_project.yml | 24 +- dbt/minc/models/metadata/models_metadata.sql | 51 + dbt/minc/models/metadata/schema.yml | 19 + dbt/minc/models/sources.yml | 10 + dbt/{ipea => minc}/profiles.yml | 4 +- dbt/mir/.user.yml | 1 - dbt/mir/descriptions.yml | 0 dbt/mir/macros/create_udfs.sql | 10 - .../macros/data_quality/row_count_match.sql | 14 - .../data_quality/verificacao_tipagem.sql | 25 - dbt/mir/macros/get_custom_schema.sql | 4 - dbt/mir/macros/metadata/generate_metadata.sql | 46 - dbt/mir/macros/parse_financial_value.sql | 21 - dbt/mir/macros/schema.yml | 24 - dbt/mir/macros/udfs/f_format_nc.sql | 19 - dbt/mir/macros/udfs/f_parse_dates.sql | 44 - .../dados_abertos_dbt/bronze/deputados.sql | 19 - .../dados_abertos_dbt/bronze/schema.yml | 196 --- .../dados_abertos_dbt/bronze/senadores.sql | 20 - .../silver/parlamentares.sql | 77 -- .../dados_abertos_dbt/silver/schema.yml | 80 -- .../emendas_dbt/bronze/documentos_habeis.sql | 33 - .../emendas_dbt/bronze/empenhos_especiais.sql | 38 - .../models/emendas_dbt/bronze/executor.sql | 28 - .../models/emendas_dbt/bronze/finalidades.sql | 16 - .../bronze/historico_pagamentos.sql | 16 - dbt/mir/models/emendas_dbt/bronze/metas.sql | 27 - .../emendas_dbt/bronze/ordens_bancarias.sql | 24 - .../emendas_dbt/bronze/planos_acoes.sql | 38 - .../bronze/planos_trabalho_especial.sql | 22 - .../models/emendas_dbt/bronze/programas.sql | 30 - .../emendas_dbt/bronze/relatorio_gestao.sql | 15 - .../bronze/relatorio_gestao_novo.sql | 18 - dbt/mir/models/emendas_dbt/bronze/schema.yml | 1132 ----------------- .../models/emendas_dbt/bronze/tg_emendas.sql | 53 - .../emendas_dbt/silver/planos_partidos.sql | 96 -- dbt/mir/models/emendas_dbt/silver/schema.yml | 168 --- .../bronze/empenhos_tesouro_ted.sql | 37 - .../empenhos_ted_dbt/bronze/schema.yaml | 102 -- dbt/mir/models/metadata/models_metadata.sql | 67 - dbt/mir/models/metadata/schema.yml | 46 - dbt/mir/models/sources.yml | 34 - dbt/mir/profiles.yml | 11 - dbt/mir/seeds/partidos_logo.csv | 29 - dbt/mir/seeds/partidos_map.csv | 2 - dbt/mir/seeds/schema.yml | 14 - .../tests/test_parlamentares_logo_partido.sql | 19 - infra/airflow/prune_stale_dags.py | 36 + .../simple_auth_manager_passwords.json | 1 + infra/docker-compose.yml | 57 +- infra/docker/airflow/Dockerfile | 14 +- infra/env/.env.example | 7 +- local.env | 4 +- plugins/schedule_loader.py | 4 +- pyproject.toml | 21 +- requirements.txt | 11 +- .../siape/consultaDadosAfastamento.xml.j2 | 15 - .../consultaDadosAfastamentoHistorico.xml.j2 | 19 - templates/siape/consultaDadosCurriculo.xml.j2 | 15 - .../siape/consultaDadosDependentes.xml.j2 | 15 - templates/siape/consultaDadosEscolares.xml.j2 | 15 - .../siape/consultaDadosFinanceiros.xml.j2 | 15 - .../siape/consultaDadosFuncionais.xml.j2 | 14 - templates/siape/consultaDadosPA.xml.j2 | 15 - templates/siape/consultaDadosPessoais.xml.j2 | 15 - templates/siape/consultaDadosUorg.xml.j2 | 15 - .../siape/consultaPensoesInstituidas.xml.j2 | 15 - .../listaInformacoesAposentadoria.xml.j2 | 14 - templates/siape/listaServidores.xml.j2 | 14 - templates/siape/listaUorgs.xml.j2 | 13 - 227 files changed, 324 insertions(+), 16521 deletions(-) delete mode 100644 dags/dashboards/__init__.py delete mode 100644 dags/dashboards/dashboard_servidores_dag.py delete mode 100755 dags/data_ingest/compras_gov/contratos_inativos_ingest_dag.py delete mode 100755 dags/data_ingest/compras_gov/contratos_ingest_dag.py delete mode 100755 dags/data_ingest/compras_gov/cronograma_ingest_dag.py delete mode 100755 dags/data_ingest/compras_gov/empenhos_ingest_dag.py delete mode 100755 dags/data_ingest/compras_gov/faturas_ingest_dag.py delete mode 100644 dags/data_ingest/compras_gov/terceirizados_ingest_dag.py delete mode 100644 dags/data_ingest/dados_abertos/deputados_ingest_dag.py delete mode 100644 dags/data_ingest/dados_abertos/senadores_ingest_dag.py delete mode 100644 dags/data_ingest/pncp/itens_resultados_licitacoes.py delete mode 100644 dags/data_ingest/pncp/licitacoes_ingest.py delete mode 100644 dags/data_ingest/sgac/projetos_sgac_ingest_dag.py delete mode 100644 dags/data_ingest/siafi/nota_credito_siafi_ingest_dag.py delete mode 100644 dags/data_ingest/siafi/nota_empenho_siafi_ingest_dag.py delete mode 100644 dags/data_ingest/siafi/programacao_financeira_siafi_ingest_dag.py delete mode 100644 dags/data_ingest/siape/dados_afastamento_historico_siape_ingest_dag.py delete mode 100644 dags/data_ingest/siape/dados_afastamento_siape_ingest_dag.py delete mode 100644 dags/data_ingest/siape/dados_curriculo_siape_ingest_dag.py delete mode 100644 dags/data_ingest/siape/dados_dependentes_siape_ingest_dag.py delete mode 100644 dags/data_ingest/siape/dados_escolares_siape_ingest_dag.py delete mode 100644 dags/data_ingest/siape/dados_financeiros_siape_dag.py delete mode 100644 dags/data_ingest/siape/dados_funcionais_siape_ingest_dag.py delete mode 100644 dags/data_ingest/siape/dados_pa_siape_ingest_dag.py delete mode 100644 dags/data_ingest/siape/dados_pessoais_siape_ingest_dag.py delete mode 100644 dags/data_ingest/siape/dados_uorg_siape_ingest_dag.py delete mode 100644 dags/data_ingest/siape/lista_aposentadoria_siape_ingest_dag.py delete mode 100644 dags/data_ingest/siape/lista_servidores_siape_ingest_dag.py delete mode 100644 dags/data_ingest/siape/lista_uorgs_siape_ingest_dag.py delete mode 100644 dags/data_ingest/siape/pensoes_instituidas_siape_ingest_dag.py delete mode 100644 dags/data_ingest/siorg/cargos_funcao_ingest_dag.py delete mode 100644 dags/data_ingest/siorg/estrutura_organizacional_cargos_ingest_dag.py delete mode 100755 dags/data_ingest/siorg/unidade_organizacional_ingest_dag.py delete mode 100644 dags/data_ingest/tesouro_gerencial/empenhos_tesouro_emendas_ingest_dag.py delete mode 100755 dags/data_ingest/tesouro_gerencial/empenhos_tesouro_ingest_dag.py delete mode 100644 dags/data_ingest/tesouro_gerencial/mcid/dotacao_execucao_outras_fontes_mcid_ingest_dag.py delete mode 100644 dags/data_ingest/tesouro_gerencial/mcid/empenho_emendas_parlamentares_ingest_dag.py delete mode 100644 dags/data_ingest/tesouro_gerencial/mcid/orcamento_mcid_por_acao_ingest_dag.py delete mode 100644 dags/data_ingest/tesouro_gerencial/mir/empenhos_tesouro_parlamentares_ingest_dag.py delete mode 100644 dags/data_ingest/tesouro_gerencial/nc_tesouro_ingest.dag.py delete mode 100644 dags/data_ingest/tesouro_gerencial/pf_tesouro_ingest_dag.py delete mode 100644 dags/data_ingest/tesouro_gerencial/visao_orcamentaria_ingest.py delete mode 100644 dags/data_ingest/transfere_gov/mir/notas_de_credito_ingest_mir_dag.py delete mode 100644 dags/data_ingest/transfere_gov/mir/plano_acao_ingest_mir_dag.py delete mode 100644 dags/data_ingest/transfere_gov/mir/programa_financeira_ingest_mir_dag.py delete mode 100644 dags/data_ingest/transfere_gov/mir/programas_ingest_mir_dag.py delete mode 100644 dags/data_ingest/transfere_gov/notas_de_credito_ingest_dag.py delete mode 100644 dags/data_ingest/transfere_gov/plano_acao_ingest_dag.py delete mode 100644 dags/data_ingest/transfere_gov/programa_beneficiario_ingest_dag.py delete mode 100644 dags/data_ingest/transfere_gov/programacao_financeira_ingest_dag.py delete mode 100644 dags/data_ingest/transfere_gov/programas_ingest_dag.py delete mode 100644 dags/data_ingest/transferegov_emendas/documentos_habeis_especias_ingest_dag.py delete mode 100644 dags/data_ingest/transferegov_emendas/empenhos_especiais_ingest_dag.py delete mode 100644 dags/data_ingest/transferegov_emendas/executor_especial_ingest_dag.py delete mode 100644 dags/data_ingest/transferegov_emendas/finalidade_especial_ingest_dag.py delete mode 100644 dags/data_ingest/transferegov_emendas/historico_pagamentos_especiais_ingest_dag.py delete mode 100644 dags/data_ingest/transferegov_emendas/metas_especiais_ingest_dag.py delete mode 100644 dags/data_ingest/transferegov_emendas/ordem_bancaria_especial_ingest_dag.py delete mode 100644 dags/data_ingest/transferegov_emendas/plano_trabalho_especial_ingest_dag.py delete mode 100644 dags/data_ingest/transferegov_emendas/planos_acao_especiais_ingest_dag.py delete mode 100644 dags/data_ingest/transferegov_emendas/programas_especiais_ingest_dag.py delete mode 100644 dags/data_ingest/transferegov_emendas/relatorio_gestao_novo_especial_ingest_dag.py delete mode 100644 dags/data_ingest/transferegov_emendas/reltorio_gestao_ingest.py rename dags/data_ingest/{transfere_gov/minc/minc_api_anexos_relatorios_dag.py => transferegov_fundo_a_fundo/api_anexos_relatorios_dag.py} (65%) rename dags/data_ingest/{transfere_gov/minc/minc_api_planos_acao_dag.py => transferegov_fundo_a_fundo/api_planos_acao_dag.py} (64%) rename dags/data_ingest/{transfere_gov/minc => transferegov_fundo_a_fundo}/api_programas_dag.py (71%) rename dags/data_ingest/{transfere_gov/minc/minc_api_relatorios_gestao_dag.py => transferegov_fundo_a_fundo/api_relatorios_gestao_dag.py} (66%) rename dags/data_ingest/{transfere_gov/minc/minc_download_anexos_dag.py => transferegov_fundo_a_fundo/download_anexos_dag.py} (92%) rename dags/data_ingest/{transfere_gov/minc/minc_extracao_anexos_dag.py => transferegov_fundo_a_fundo/extracao_anexos_dag.py} (91%) rename dags/dbt/{ipea_cosmos_dag.py => minc_cosmos_dag.py} (60%) mode change 100755 => 100644 delete mode 100755 dags/dbt/mir_cosmos_dag.py delete mode 100755 dbt/ipea/.user.yml delete mode 100755 dbt/ipea/dbt_project.yml delete mode 100644 dbt/ipea/descriptions.yml delete mode 100644 dbt/ipea/macros/create_udfs.sql delete mode 100644 dbt/ipea/macros/data_quality/row_count_match.sql delete mode 100644 dbt/ipea/macros/data_quality/verificacao_tipagem.sql delete mode 100755 dbt/ipea/macros/get_custom_schema.sql delete mode 100644 dbt/ipea/macros/metadata/generate_metadata.sql delete mode 100644 dbt/ipea/macros/parse_financial_value.sql delete mode 100644 dbt/ipea/macros/schema.yml delete mode 100644 dbt/ipea/macros/udfs/f_format_nc.sql delete mode 100644 dbt/ipea/macros/udfs/f_parse_dates.sql delete mode 100755 dbt/ipea/models/contratos_dbt/bronze/contratos.sql delete mode 100644 dbt/ipea/models/contratos_dbt/bronze/cronogramas.sql delete mode 100755 dbt/ipea/models/contratos_dbt/bronze/empenhos.sql delete mode 100755 dbt/ipea/models/contratos_dbt/bronze/empenhos_tesouro.sql delete mode 100755 dbt/ipea/models/contratos_dbt/bronze/faturas.sql delete mode 100644 dbt/ipea/models/contratos_dbt/bronze/schema.yml delete mode 100644 dbt/ipea/models/contratos_dbt/gold/contratos_comparativo_mensal.sql delete mode 100755 dbt/ipea/models/contratos_dbt/gold/contratos_resumo.sql delete mode 100644 dbt/ipea/models/contratos_dbt/gold/contratos_somatorio.sql delete mode 100644 dbt/ipea/models/contratos_dbt/gold/schema.yml delete mode 100755 dbt/ipea/models/contratos_dbt/silver/contratos_empenhos.sql delete mode 100644 dbt/ipea/models/contratos_dbt/silver/contratos_estagios.sql delete mode 100644 dbt/ipea/models/contratos_dbt/silver/contratos_faturas.sql delete mode 100644 dbt/ipea/models/contratos_dbt/silver/cronogramas_faturas_mensal.sql delete mode 100644 dbt/ipea/models/contratos_dbt/silver/estagios_mensal.sql delete mode 100644 dbt/ipea/models/contratos_dbt/silver/schema.yml delete mode 100644 dbt/ipea/models/contratos_dbt/views/identificadores.sql delete mode 100644 dbt/ipea/models/contratos_dbt/views/preenchimento_meses.sql delete mode 100644 dbt/ipea/models/contratos_dbt/views/schema.yml delete mode 100644 dbt/ipea/models/metadata/models_metadata.sql delete mode 100644 dbt/ipea/models/metadata/schema.yml delete mode 100644 dbt/ipea/models/orcamento_dbt/bronze/schema.yml delete mode 100644 dbt/ipea/models/orcamento_dbt/bronze/visao_orcamentaria_total.sql delete mode 100644 dbt/ipea/models/pessoas_dbt/bronze/afastamento_historico.sql delete mode 100644 dbt/ipea/models/pessoas_dbt/bronze/cargos_funcoes.sql delete mode 100644 dbt/ipea/models/pessoas_dbt/bronze/dados_afastamento.sql delete mode 100644 dbt/ipea/models/pessoas_dbt/bronze/dados_curriculo.sql delete mode 100644 dbt/ipea/models/pessoas_dbt/bronze/dados_dependentes.sql delete mode 100644 dbt/ipea/models/pessoas_dbt/bronze/dados_escolares.sql delete mode 100644 dbt/ipea/models/pessoas_dbt/bronze/dados_financeiros.sql delete mode 100644 dbt/ipea/models/pessoas_dbt/bronze/dados_funcionais.sql delete mode 100644 dbt/ipea/models/pessoas_dbt/bronze/dados_pa.sql delete mode 100644 dbt/ipea/models/pessoas_dbt/bronze/dados_pessoais.sql delete mode 100644 dbt/ipea/models/pessoas_dbt/bronze/dados_uorg.sql delete mode 100644 dbt/ipea/models/pessoas_dbt/bronze/estrutura_organizacional_cargos.sql delete mode 100644 dbt/ipea/models/pessoas_dbt/bronze/lista_servidores.sql delete mode 100644 dbt/ipea/models/pessoas_dbt/bronze/lista_uorgs.sql delete mode 100644 dbt/ipea/models/pessoas_dbt/bronze/schema.yml delete mode 100644 dbt/ipea/models/pessoas_dbt/bronze/terceirizados.sql delete mode 100644 dbt/ipea/models/pessoas_dbt/bronze/unidade_organizacional.sql delete mode 100644 dbt/ipea/models/pessoas_dbt/gold/aposentadorias_resumo.sql delete mode 100644 dbt/ipea/models/pessoas_dbt/gold/cargos_consolidado.sql delete mode 100644 dbt/ipea/models/pessoas_dbt/gold/distribuicao_genero.sql delete mode 100644 dbt/ipea/models/pessoas_dbt/gold/distribuicao_mapa_uf.sql delete mode 100644 dbt/ipea/models/pessoas_dbt/gold/distribuicao_raca_cor.sql delete mode 100644 dbt/ipea/models/pessoas_dbt/gold/distribuicao_situacao_funcional.sql delete mode 100644 dbt/ipea/models/pessoas_dbt/gold/hierarquia.sql delete mode 100644 dbt/ipea/models/pessoas_dbt/gold/kpis_servidores.sql delete mode 100644 dbt/ipea/models/pessoas_dbt/gold/resumo_quadro_pessoal.sql delete mode 100644 dbt/ipea/models/pessoas_dbt/gold/schema.yml delete mode 100644 dbt/ipea/models/pessoas_dbt/gold/tabela_servidores_agregada.sql delete mode 100644 dbt/ipea/models/pessoas_dbt/silver/afastamento_consolidado.sql delete mode 100644 dbt/ipea/models/pessoas_dbt/silver/quantitativo_alocados_ocupados.sql delete mode 100644 dbt/ipea/models/pessoas_dbt/silver/schema.yml delete mode 100644 dbt/ipea/models/pessoas_dbt/silver/servidores_completos.sql delete mode 100644 dbt/ipea/models/pessoas_dbt/silver/servidores_detalhados.sql delete mode 100644 dbt/ipea/models/pessoas_dbt/silver/tabela_correlacao_cargos.sql delete mode 100644 dbt/ipea/models/pessoas_dbt/silver/unidades_organizacionais_siorg_siape.sql delete mode 100644 dbt/ipea/models/sources.yml delete mode 100644 dbt/ipea/models/ted_dbt/bronze/nc_tesouro.sql delete mode 100644 dbt/ipea/models/ted_dbt/bronze/pf_tesouro.sql delete mode 100644 dbt/ipea/models/ted_dbt/bronze/planos_acao.sql delete mode 100644 dbt/ipea/models/ted_dbt/bronze/schema.yml delete mode 100644 dbt/ipea/models/ted_dbt/gold/schema.yml delete mode 100644 dbt/ipea/models/ted_dbt/gold/ted_resumo_orcamentario.sql delete mode 100644 dbt/ipea/models/ted_dbt/silver/empenhos_plano_acao.sql delete mode 100644 dbt/ipea/models/ted_dbt/silver/nc_plano_acao.sql delete mode 100644 dbt/ipea/models/ted_dbt/silver/pf_plano_acao.sql delete mode 100644 dbt/ipea/models/ted_dbt/silver/schema.yml delete mode 100644 dbt/ipea/models/ted_dbt/views/num_transf_n_plano_acao.sql delete mode 100644 dbt/ipea/models/ted_dbt/views/schema.yml delete mode 100644 dbt/ipea/seeds/estados_brasil.csv delete mode 100644 dbt/ipea/snapshots/tables_snapshot.yml rename dbt/{mir => minc}/dbt_project.yml (50%) mode change 100755 => 100644 create mode 100644 dbt/minc/models/metadata/models_metadata.sql create mode 100644 dbt/minc/models/metadata/schema.yml create mode 100644 dbt/minc/models/sources.yml rename dbt/{ipea => minc}/profiles.yml (85%) mode change 100755 => 100644 delete mode 100755 dbt/mir/.user.yml delete mode 100644 dbt/mir/descriptions.yml delete mode 100644 dbt/mir/macros/create_udfs.sql delete mode 100644 dbt/mir/macros/data_quality/row_count_match.sql delete mode 100644 dbt/mir/macros/data_quality/verificacao_tipagem.sql delete mode 100755 dbt/mir/macros/get_custom_schema.sql delete mode 100644 dbt/mir/macros/metadata/generate_metadata.sql delete mode 100644 dbt/mir/macros/parse_financial_value.sql delete mode 100644 dbt/mir/macros/schema.yml delete mode 100644 dbt/mir/macros/udfs/f_format_nc.sql delete mode 100644 dbt/mir/macros/udfs/f_parse_dates.sql delete mode 100644 dbt/mir/models/dados_abertos_dbt/bronze/deputados.sql delete mode 100644 dbt/mir/models/dados_abertos_dbt/bronze/schema.yml delete mode 100644 dbt/mir/models/dados_abertos_dbt/bronze/senadores.sql delete mode 100644 dbt/mir/models/dados_abertos_dbt/silver/parlamentares.sql delete mode 100644 dbt/mir/models/dados_abertos_dbt/silver/schema.yml delete mode 100644 dbt/mir/models/emendas_dbt/bronze/documentos_habeis.sql delete mode 100644 dbt/mir/models/emendas_dbt/bronze/empenhos_especiais.sql delete mode 100644 dbt/mir/models/emendas_dbt/bronze/executor.sql delete mode 100644 dbt/mir/models/emendas_dbt/bronze/finalidades.sql delete mode 100644 dbt/mir/models/emendas_dbt/bronze/historico_pagamentos.sql delete mode 100644 dbt/mir/models/emendas_dbt/bronze/metas.sql delete mode 100644 dbt/mir/models/emendas_dbt/bronze/ordens_bancarias.sql delete mode 100644 dbt/mir/models/emendas_dbt/bronze/planos_acoes.sql delete mode 100644 dbt/mir/models/emendas_dbt/bronze/planos_trabalho_especial.sql delete mode 100644 dbt/mir/models/emendas_dbt/bronze/programas.sql delete mode 100644 dbt/mir/models/emendas_dbt/bronze/relatorio_gestao.sql delete mode 100644 dbt/mir/models/emendas_dbt/bronze/relatorio_gestao_novo.sql delete mode 100644 dbt/mir/models/emendas_dbt/bronze/schema.yml delete mode 100644 dbt/mir/models/emendas_dbt/bronze/tg_emendas.sql delete mode 100644 dbt/mir/models/emendas_dbt/silver/planos_partidos.sql delete mode 100644 dbt/mir/models/emendas_dbt/silver/schema.yml delete mode 100644 dbt/mir/models/empenhos_ted_dbt/bronze/empenhos_tesouro_ted.sql delete mode 100644 dbt/mir/models/empenhos_ted_dbt/bronze/schema.yaml delete mode 100644 dbt/mir/models/metadata/models_metadata.sql delete mode 100644 dbt/mir/models/metadata/schema.yml delete mode 100644 dbt/mir/models/sources.yml delete mode 100755 dbt/mir/profiles.yml delete mode 100644 dbt/mir/seeds/partidos_logo.csv delete mode 100644 dbt/mir/seeds/partidos_map.csv delete mode 100644 dbt/mir/seeds/schema.yml delete mode 100644 dbt/mir/tests/test_parlamentares_logo_partido.sql create mode 100644 infra/airflow/prune_stale_dags.py create mode 100644 infra/airflow/simple_auth_manager_passwords.json delete mode 100644 templates/siape/consultaDadosAfastamento.xml.j2 delete mode 100644 templates/siape/consultaDadosAfastamentoHistorico.xml.j2 delete mode 100644 templates/siape/consultaDadosCurriculo.xml.j2 delete mode 100644 templates/siape/consultaDadosDependentes.xml.j2 delete mode 100644 templates/siape/consultaDadosEscolares.xml.j2 delete mode 100644 templates/siape/consultaDadosFinanceiros.xml.j2 delete mode 100644 templates/siape/consultaDadosFuncionais.xml.j2 delete mode 100644 templates/siape/consultaDadosPA.xml.j2 delete mode 100644 templates/siape/consultaDadosPessoais.xml.j2 delete mode 100644 templates/siape/consultaDadosUorg.xml.j2 delete mode 100644 templates/siape/consultaPensoesInstituidas.xml.j2 delete mode 100644 templates/siape/listaInformacoesAposentadoria.xml.j2 delete mode 100644 templates/siape/listaServidores.xml.j2 delete mode 100644 templates/siape/listaUorgs.xml.j2 diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 63b21896..f605387e 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -19,10 +19,10 @@ env: POETRY_VERSION: "1.8.5" POETRY_VIRTUALENVS_IN_PROJECT: "true" POETRY_CACHE_DIR: "/home/runner/.cache/poetry" - DBT_PROJECT_DIR: "${{ github.workspace }}/dbt/ipea" + DBT_PROJECT_DIR: "${{ github.workspace }}/dbt/minc" IMAGE_REGISTRY_OWNER: govhub-br - IMAGE_NAME: ghcr.io/govhub-br/airflow-ipea + IMAGE_NAME: ghcr.io/govhub-br/airflow-minc IMAGE_TAG_SHA: ${{ github.sha }} jobs: diff --git a/dags/dashboards/__init__.py b/dags/dashboards/__init__.py deleted file mode 100644 index da6b0a9a..00000000 --- a/dags/dashboards/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -""" -Módulo de DAGs para geração de dashboards. -""" diff --git a/dags/dashboards/dashboard_servidores_dag.py b/dags/dashboards/dashboard_servidores_dag.py deleted file mode 100644 index d79f1578..00000000 --- a/dags/dashboards/dashboard_servidores_dag.py +++ /dev/null @@ -1,168 +0,0 @@ -""" -DAG para gerar arquivo JSON com dados do dashboard de servidores. -""" - -import json -import logging -from datetime import datetime, timedelta -from typing import Dict - -from airflow.decorators import dag, task -from airflow.models import Variable - -from postgres_helpers import get_postgres_conn -from cliente_postgres import ClientPostgresDB -from cliente_github import ClienteGitHub - -# Configuração de logging -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger(__name__) - -# Configurações do GitHub -GITHUB_OWNER = "GovHub-br" -GITHUB_REPO = "gov-hub" -GITHUB_FILE_PATH = "docs/land/public/data/pessoas_visao_geral.json" -GITHUB_BRANCH = "main" - - -@dag( - dag_id="dashboard_servidores_json", - schedule_interval="0 6 * * *", # Executa diariamente às 6h - start_date=datetime(2025, 11, 16), - catchup=False, - default_args={ - "owner": "Davi", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["dashboard", "pessoas", "json"], - description="Gera arquivo JSON com dados do dashboard de servidores", -) -def dashboard_servidores_dag() -> None: - """ - DAG que gera arquivo JSON consolidado com dados do dashboard de servidores. - """ - - @task - def generate_dashboard_json() -> Dict: - """ - Gera dados do dashboard de servidores. - - Returns: - Dicionário com os dados do dashboard - """ - logger.info("Iniciando geração dos dados do dashboard") - - try: - # Conectar ao banco de dados usando helper - postgres_conn_str = get_postgres_conn() - client = ClientPostgresDB(postgres_conn_str) - logger.info("Conectado ao banco de dados com sucesso") - - # Buscar dados - logger.info("Buscando KPIs...") - kpis = client.get_dashboard_kpis() - - logger.info("Buscando distribuição por gênero...") - genero = client.get_dashboard_genero() - - logger.info("Buscando distribuição por raça/cor...") - raca_cor = client.get_dashboard_raca_cor() - - logger.info("Buscando distribuição por situação funcional...") - situacao_funcional = client.get_dashboard_situacao_funcional() - - logger.info("Buscando distribuição geográfica por UF...") - mapa_uf = client.get_dashboard_mapa_uf() - - logger.info("Buscando tabela de servidores agregada...") - tabela_servidores = client.get_dashboard_tabela_servidores(limit=100) - - # Montar estrutura do JSON - dashboard_data = { - "meta": {"atualizado_em": datetime.now().isoformat() + "Z"}, - "kpis": { - "total_servidores": kpis.get("total_servidores", 0), - "servidores_ativos_permanentes": kpis.get( - "servidores_ativos_permanentes", 0 - ), - "aposentados": kpis.get("aposentados", 0), - "estagiarios": kpis.get("estagiarios", 0), - "terceirizados": kpis.get("terceirizados", 0), - }, - "genero": genero, - "raca_cor": raca_cor, - "mapa_uf": mapa_uf, - "situacao_funcional": situacao_funcional, - "tabela_servidores": tabela_servidores, - } - - return dashboard_data - - except Exception as e: - logger.error(f"Erro ao gerar dados do dashboard: {str(e)}") - raise - - @task - def publish_to_github(dashboard_data: Dict) -> Dict[str, str]: - """ - Publica os dados do dashboard no repositório GitHub. - - Args: - dashboard_data: Dicionário com os dados do dashboard - - Returns: - Informações sobre o commit realizado - """ - logger.info("Iniciando publicação dos dados no GitHub") - - try: - # Obter token do GitHub das variáveis do Airflow - github_token = Variable.get("GITHUB_TOKEN") - logger.info("Token do GitHub obtido com sucesso") - - # Converter dicionário para JSON string - json_content = json.dumps(dashboard_data, ensure_ascii=False, indent=2) - logger.info("Dados convertidos para JSON") - - # Inicializar cliente GitHub - github_client = ClienteGitHub(github_token) - - # Criar mensagem de commit - commit_message = ( - f"Update dashboard data - {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}" - ) - - # Publicar no GitHub - logger.info(f"Publicando em {GITHUB_OWNER}/{GITHUB_REPO}:{GITHUB_FILE_PATH}") - result = github_client.update_file( - owner=GITHUB_OWNER, - repo=GITHUB_REPO, - path=GITHUB_FILE_PATH, - content=json_content, - message=commit_message, - branch=GITHUB_BRANCH, - ) - - commit_info = { - "commit_sha": result.get("commit", {}).get("sha", ""), - "commit_url": result.get("commit", {}).get("html_url", ""), - "file_url": result.get("content", {}).get("html_url", ""), - } - - logger.info("Arquivo publicado com sucesso no GitHub!") - logger.info(f"Commit SHA: {commit_info['commit_sha']}") - logger.info(f"URL do arquivo: {commit_info['file_url']}") - - return commit_info - - except Exception as e: - logger.error(f"Erro ao publicar no GitHub: {str(e)}") - raise - - # Definir dependências entre tasks usando XCom - dashboard_data = generate_dashboard_json() - publish_to_github(dashboard_data) - - -dag_instance = dashboard_servidores_dag() diff --git a/dags/data_ingest/compras_gov/contratos_inativos_ingest_dag.py b/dags/data_ingest/compras_gov/contratos_inativos_ingest_dag.py deleted file mode 100755 index 9f06fbc8..00000000 --- a/dags/data_ingest/compras_gov/contratos_inativos_ingest_dag.py +++ /dev/null @@ -1,72 +0,0 @@ -import logging -import yaml -from airflow.decorators import dag, task -from airflow.models import Variable -from datetime import datetime, timedelta -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_contratos import ClienteContratos -from cliente_postgres import ClientPostgresDB - - -@dag( - schedule_interval=get_dynamic_schedule("contratos_inativos_ingest_dag"), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "owner": "Davi", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["contratos_inativos_api", "compras_gov"], -) -def api_contratos_inativos_dag() -> None: - """DAG para buscar e armazenar contratos inativos de uma API no PostgreSQL.""" - - @task - def fetch_and_store_contratos_inativos() -> None: - logging.info("Iniciando fetch_and_store_contratos_inativos") - - orgao_alvo = Variable.get("airflow_orgao", default_var=None) - if not orgao_alvo: - logging.error("Variável airflow_orgao não definida!") - raise ValueError("airflow_orgao não definida") - - orgaos_config_str = Variable.get("airflow_variables", default_var="{}") - orgaos_config = yaml.safe_load(orgaos_config_str) - - ug_codes = orgaos_config.get(orgao_alvo, {}).get("codigos_ug", []) - - if not ug_codes: - logging.warning(f"Nenhum código UG encontrado para o órgão '{orgao_alvo}'") - return - - api = ClienteContratos() - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - - for ug_code in ug_codes: - logging.info(f"Buscando contratos inativos para UG: {ug_code}") - contratos = api.get_contratos_inativos_by_ug(ug_code) - if contratos: - # Adicionar dt_ingest a cada contrato - for contrato in contratos: - contrato["dt_ingest"] = datetime.now().isoformat() - - logging.info( - f"Inserindo contratos inativos da UG {ug_code} no schema compras_gov" - ) - db.insert_data( - contratos, - "contratos", - conflict_fields=["id"], - primary_key=["id"], - schema="compras_gov", - ) - else: - logging.warning(f"Nenhum contrato inativo encontrado para UG {ug_code}") - - fetch_and_store_contratos_inativos() - - -dag_instance = api_contratos_inativos_dag() diff --git a/dags/data_ingest/compras_gov/contratos_ingest_dag.py b/dags/data_ingest/compras_gov/contratos_ingest_dag.py deleted file mode 100755 index ad789ce7..00000000 --- a/dags/data_ingest/compras_gov/contratos_ingest_dag.py +++ /dev/null @@ -1,78 +0,0 @@ -import logging -import yaml -from airflow.decorators import dag, task -from airflow.operators.trigger_dagrun import TriggerDagRunOperator -from airflow.models import Variable -from datetime import datetime, timedelta -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_contratos import ClienteContratos -from cliente_postgres import ClientPostgresDB - - -@dag( - schedule_interval=get_dynamic_schedule("contratos_ingest_dag"), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "owner": "Davi", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["contratos_api", "compras_gov"], -) -def api_contratos_dag() -> None: - """DAG para buscar e armazenar contratos por órgão definido.""" - - @task - def fetch_and_store_contratos() -> None: - logging.info("[contratos_ingest_dag.py] Iniciando extração") - - orgao_alvo = Variable.get("airflow_orgao", default_var=None) - if not orgao_alvo: - logging.error("Variável airflow_orgao não definida!") - raise ValueError("airflow_orgao não definida") - - orgaos_config_str = Variable.get("airflow_variables", default_var="{}") - orgaos_config = yaml.safe_load(orgaos_config_str) - - codigos_ug = orgaos_config.get(orgao_alvo, {}).get("codigos_ug", []) - - if not codigos_ug: - logging.warning(f"Nenhum código UG encontrado para o órgão '{orgao_alvo}'") - return - - api = ClienteContratos() - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - - for ug_code in codigos_ug: - logging.info(f"Buscando contratos para UG: {ug_code}") - contratos = api.get_contratos_by_ug(ug_code) - - if contratos: - # Adicionar dt_ingest a cada contrato - for contrato in contratos: - contrato["dt_ingest"] = datetime.now().isoformat() - - logging.info(f"Inserindo contratos da UG {ug_code} no schema compras_gov") - db.insert_data( - contratos, - "contratos", - conflict_fields=["id"], - primary_key=["id"], - schema="compras_gov", - ) - else: - logging.warning(f"Nenhum contrato encontrado para UG {ug_code}") - - trigger_contratos_inativos = TriggerDagRunOperator( - task_id="trigger_contratos_inativos", - trigger_dag_id="api_contratos_inativos_dag", - wait_for_completion=False, - ) - - fetch_and_store_contratos() >> trigger_contratos_inativos - - -dag_instance = api_contratos_dag() diff --git a/dags/data_ingest/compras_gov/cronograma_ingest_dag.py b/dags/data_ingest/compras_gov/cronograma_ingest_dag.py deleted file mode 100755 index 5eeccfc1..00000000 --- a/dags/data_ingest/compras_gov/cronograma_ingest_dag.py +++ /dev/null @@ -1,67 +0,0 @@ -import logging -from airflow.decorators import dag, task -from datetime import datetime, timedelta -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_contratos import ClienteContratos -from cliente_postgres import ClientPostgresDB - - -@dag( - schedule_interval=get_dynamic_schedule("cronograma_ingest_dag"), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["cronogramas_api", "compras_gov"], -) -def api_cronogramas_dag() -> None: - """DAG para buscar e armazenar cronogramas de uma API no PostgreSQL.""" - - @task - def fetch_cronogramas() -> None: - logging.info("[cronograma_ingest_dag.py] Starting fetch_cronogramas task") - api = ClienteContratos() - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - contratos_ids = db.get_contratos_ids() - - # Drop the existing cronograma table before inserting new data - logging.info("[cronograma_ingest_dag.py] Dropping existing cronograma table") - db.drop_table_if_exists("cronograma", schema="compras_gov") - logging.info("[cronograma_ingest_dag.py] Table dropped successfully") - - for contrato_id in contratos_ids: - logging.info( - f"[cronograma_ingest_dag.py] Fetching cronograma for contrato ID: " - f"{contrato_id}" - ) - cronograma = api.get_cronograma_by_contrato_id(contrato_id) - if cronograma: - # Adicionar dt_ingest a cada item do cronograma - for item in cronograma: - item["dt_ingest"] = datetime.now().isoformat() - - logging.info( - f"[cronograma_ingest_dag.py] Inserting cronograma for contrato ID: " - f"{contrato_id} into PostgreSQL" - ) - db.insert_data( - cronograma, - "cronograma", - conflict_fields=["id"], - primary_key=["id"], - schema="compras_gov", - ) - else: - logging.warning( - f"[cronograma_ingest_dag.py] No cronograma found for contrato ID: " - f"{contrato_id}" - ) - - fetch_cronogramas() - - -dag_instance = api_cronogramas_dag() diff --git a/dags/data_ingest/compras_gov/empenhos_ingest_dag.py b/dags/data_ingest/compras_gov/empenhos_ingest_dag.py deleted file mode 100755 index 828efb5e..00000000 --- a/dags/data_ingest/compras_gov/empenhos_ingest_dag.py +++ /dev/null @@ -1,65 +0,0 @@ -import logging -from airflow.decorators import dag, task -from datetime import datetime, timedelta -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_contratos import ClienteContratos -from cliente_postgres import ClientPostgresDB - - -@dag( - schedule_interval=get_dynamic_schedule("empenhos_ingest_dag"), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "owner": "Davi", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["empenhos_api", "compras_gov"], -) -def api_empenhos_dag() -> None: - """DAG para buscar e armazenar dados de empenhos de uma API.""" - - @task - def fetch_empenhos() -> None: - logging.info("[empenhos_ingest_dag.py] Starting fetch_empenhos task") - api = ClienteContratos() - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - contratos_ids = db.get_contratos_ids() - - for contrato_id in contratos_ids: - try: - logging.info( - f"[empenhos_ingest_dag.py] Fetching empenhos for contrato ID: " - f"{contrato_id}" - ) - empenhos = api.get_empenhos_by_contrato_id(str(contrato_id)) - - if empenhos: - for empenho in empenhos: - empenho["contrato_id"] = contrato_id - empenho["dt_ingest"] = datetime.now().isoformat() - - logging.info( - f"[empenhos_ingest_dag.py] Inserting empenhos for contrato ID: " - f"{contrato_id} into PostgreSQL" - ) - db.insert_data( - empenhos, - "empenhos", - conflict_fields=["id", "contrato_id"], - primary_key=["id", "contrato_id"], - schema="compras_gov", - ) - except Exception as e: - logging.error( - f"[empenhos_ingest_dag.py] Error fetching empenhos for contrato " - f"ID {contrato_id}: {e}" - ) - - fetch_empenhos() - - -dag_instance = api_empenhos_dag() diff --git a/dags/data_ingest/compras_gov/faturas_ingest_dag.py b/dags/data_ingest/compras_gov/faturas_ingest_dag.py deleted file mode 100755 index 62008d8f..00000000 --- a/dags/data_ingest/compras_gov/faturas_ingest_dag.py +++ /dev/null @@ -1,64 +0,0 @@ -import logging -from airflow.decorators import dag, task -from datetime import datetime, timedelta -from schedule_loader import get_dynamic_schedule -from cliente_contratos import ClienteContratos -from cliente_postgres import ClientPostgresDB -from postgres_helpers import get_postgres_conn - - -@dag( - schedule_interval=get_dynamic_schedule("faturas_ingest_dag"), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["faturas_api", "compras_gov"], -) -def api_faturas_dag() -> None: - """DAG para buscar e armazenar faturas de uma API no PostgreSQL.""" - - @task - def fetch_faturas() -> None: - logging.info("[faturas_ingest_dag.py] Starting fetch_faturas task") - api = ClienteContratos() - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - contratos_ids = db.get_contratos_ids() - - for contrato_id in contratos_ids: - try: - logging.info( - f"[faturas_ingest_dag.py] Fetching faturas for contrato ID: " - f"{contrato_id}" - ) - faturas = api.get_faturas_by_contrato_id(str(contrato_id)) - - # Adicionar dt_ingest a cada fatura - if faturas: - for fatura in faturas: - fatura["dt_ingest"] = datetime.now().isoformat() - - logging.info( - f"[faturas_ingest_dag.py] Inserting faturas for contrato ID: " - f"{contrato_id} into PostgreSQL" - ) - db.insert_data( - faturas, - "faturas", - conflict_fields=["id"], - primary_key=["id"], - schema="compras_gov", - ) - except Exception as e: - logging.error( - f"[faturas_ingest_dag.py] Error fetching faturas for contrato ID " - f"{contrato_id}: {e}" - ) - - fetch_faturas() - - -dag_instance = api_faturas_dag() diff --git a/dags/data_ingest/compras_gov/terceirizados_ingest_dag.py b/dags/data_ingest/compras_gov/terceirizados_ingest_dag.py deleted file mode 100644 index 34083e50..00000000 --- a/dags/data_ingest/compras_gov/terceirizados_ingest_dag.py +++ /dev/null @@ -1,62 +0,0 @@ -import logging -from airflow.decorators import dag, task -from datetime import datetime, timedelta -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_contratos import ClienteContratos -from cliente_postgres import ClientPostgresDB - - -@dag( - schedule_interval=get_dynamic_schedule("terceirizados_ingest_dag"), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "owner": "Davi", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["terceirizados_api", "compras_gov"], -) -def api_terceirizados_dag() -> None: - """DAG para buscar e armazenar dados de terceirizados de uma API.""" - - @task - def fetch_terceirizados() -> None: - logging.info("[terceirizados_ingest_dag.py] Starting fetch_terceirizados task") - api = ClienteContratos() - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - contratos_ids = db.get_contratos_ids() - - for contrato_id in contratos_ids: - try: - logging.info(f"Fetching terceirizados for contrato ID: " f"{contrato_id}") - terceirizados = api.get_terceirizados_by_contrato_id(str(contrato_id)) - - # Adicionar dt_ingest a cada terceirizado - if terceirizados: - for terceirizado in terceirizados: - terceirizado["dt_ingest"] = datetime.now().isoformat() - - logging.info( - f"Inserting terceirizados for contrato ID: " - f"{contrato_id} into PostgreSQL" - ) - db.insert_data( - terceirizados, - "terceirizados", - conflict_fields=["id"], - primary_key=["id"], - schema="compras_gov", - ) - except Exception as e: - logging.error( - f"[terceirizados_ingest_dag.py] Error fetching terceirizados for " - f"contrato ID {contrato_id}: {e}" - ) - - fetch_terceirizados() - - -dag_instance = api_terceirizados_dag() diff --git a/dags/data_ingest/dados_abertos/deputados_ingest_dag.py b/dags/data_ingest/dados_abertos/deputados_ingest_dag.py deleted file mode 100644 index 24ae2bb5..00000000 --- a/dags/data_ingest/dados_abertos/deputados_ingest_dag.py +++ /dev/null @@ -1,77 +0,0 @@ -import logging -from airflow.decorators import dag, task -from datetime import datetime, timedelta -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_deputados import ClienteDeputados -from cliente_postgres import ClientPostgresDB - - -@dag( - schedule_interval=get_dynamic_schedule("deputados_ingest_dag"), - start_date=datetime(2025, 1, 1), - catchup=False, - default_args={ - "owner": "Leonardo e Mateus", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["camara_deputados", "deputados", "dados_abertos", "MIR"], -) -def deputados_ingest_dag() -> None: - """DAG para buscar e armazenar dados de deputados da Câmara dos Deputados.""" - - @task - def fetch_and_store_deputados() -> None: - logging.info("[deputados_ingest_dag.py] Iniciando extração de deputados") - - api = ClienteDeputados() - postgres_conn_str = get_postgres_conn("postgres_mir") - db = ClientPostgresDB(postgres_conn_str) - - deputados_data = api.get_all_deputados() - - unique_key = ["id", "siglapartido", "idlegislatura"] - - if deputados_data: - vistos = set() - lista_limpa = [] - - for item in deputados_data: - - if item.get("siglaPartido") is None: - item["siglaPartido"] = "Sem Partido" - - chave_unica = tuple(item.get(key) for key in unique_key) - - if chave_unica not in vistos: - item["dt_ingest"] = datetime.now().isoformat() - lista_limpa.append(item) - vistos.add(chave_unica) - - deputados_data = lista_limpa - - logging.info( - f"[deputados_ingest_dag.py] Inserindo " - f"{len(deputados_data)} deputados no schema camara_deputados" - ) - - db.insert_data( - deputados_data, - "deputados", - conflict_fields=["id", "siglapartido", "idlegislatura"], - primary_key=["id", "siglapartido", "idlegislaturax "], - schema="camara_deputados", - ) - - logging.info( - f"[deputados_ingest_dag.py] Concluído. " - f"Total de {len(deputados_data)} registros processados." - ) - else: - logging.warning("[deputados_ingest_dag.py] Nenhum deputado encontrado") - - fetch_and_store_deputados() - - -deputados_ingest_dag() diff --git a/dags/data_ingest/dados_abertos/senadores_ingest_dag.py b/dags/data_ingest/dados_abertos/senadores_ingest_dag.py deleted file mode 100644 index 89804420..00000000 --- a/dags/data_ingest/dados_abertos/senadores_ingest_dag.py +++ /dev/null @@ -1,73 +0,0 @@ -import logging -from airflow.decorators import dag, task -from datetime import datetime, timedelta -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_senadores import ClienteSenadores -from cliente_postgres import ClientPostgresDB - - -@dag( - schedule_interval=get_dynamic_schedule("senadores_ingest_dag"), - start_date=datetime(2025, 1, 1), - catchup=False, - default_args={ - "owner": "Cibelly", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["senado_federal", "senadores", "dados_abertos", "MIR"], -) -def senadores_ingest_dag() -> None: - """DAG para buscar e armazenar dados de senadores do Senado Federal.""" - - @task - def fetch_and_store_senadores() -> None: - logging.info("[senadores_ingest_dag.py] Iniciando extração de senadores") - - api = ClienteSenadores() - postgres_conn_str = get_postgres_conn("postgres_mir") - db = ClientPostgresDB(postgres_conn_str) - - senadores_data = api.get_senadores_atuais() - - if senadores_data and len(senadores_data) > 0: - registros_limpos = [] - - for item in senadores_data: - info = item.get("IdentificacaoParlamentar", {}) - mandato = item.get("Mandato", {}) - - senador_simplificado = { - "id": info.get("CodigoParlamentar"), - "nome_parlamentar": info.get("NomeParlamentar"), - "nome_completo": info.get("NomeCompletoParlamentar"), - "sexo": info.get("SexoParlamentar"), - "forma_tratamento": info.get("FormaTratamento"), - "url_foto": info.get("UrlFotoParlamentar"), - "url_pagina": info.get("UrlPaginaParlamentar"), - "email": info.get("EmailParlamentar"), - "sigla_partido": info.get("SiglaPartidoParlamentar"), - "uf": info.get("UfParlamentar"), - "id_legislatura": mandato.get("CodigoLegislatura"), - "dt_ingest": datetime.now().isoformat(), - } - registros_limpos.append(senador_simplificado) - - logging.info( - f"[senadores_ingest_dag.py] Inserindo {len(registros_limpos)} " - f"senadores simplificados no schema senado_federal" - ) - - db.insert_data( - registros_limpos, - "senadores", - conflict_fields=["id"], - primary_key=["id"], - schema="senado_federal", - ) - - fetch_and_store_senadores() - - -senadores_ingest_dag() diff --git a/dags/data_ingest/pncp/itens_resultados_licitacoes.py b/dags/data_ingest/pncp/itens_resultados_licitacoes.py deleted file mode 100644 index 533d15b1..00000000 --- a/dags/data_ingest/pncp/itens_resultados_licitacoes.py +++ /dev/null @@ -1,157 +0,0 @@ -import logging -from datetime import datetime, timedelta - -from airflow.decorators import dag, task - -from postgres_helpers import get_postgres_conn -from cliente_postgres import ClientPostgresDB -from cliente_pncp import ClientePNCP - - -def padronizar_colunas_json(lista_de_dicts: list[dict]) -> list[dict]: - """ - Padroniza uma lista de dicionários para garantir que todos tenham as mesmas chaves. - Caso alguma coluna esteja ausente, será preenchida com None (null no banco). - - Args: - lista_de_dicts: Lista de dicionários JSON já flattenizados. - - Returns: - Lista de dicionários padronizados com todas as chaves presentes. - """ - todas_as_chaves: set[str] = set() - for item in lista_de_dicts: - todas_as_chaves.update(item.keys()) - - for item in lista_de_dicts: - for chave in todas_as_chaves: - item.setdefault(chave, None) - - return lista_de_dicts - - -@dag( - schedule_interval="@daily", - start_date=datetime(2024, 12, 5), - catchup=False, - default_args={ - "owner": "Mateus", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["pncp", "compras_publicas", "itens_resultados"], -) -def pncp_contratacoes_itens_resultados_dag() -> None: - """ - DAG responsável por buscar **ITENS** e **RESULTADOS** das contratações no PNCP. - - Fluxo: - 1. Ler da tabela `pncp.contratacoes_publicacao` todos os valores de - `numeroControlePNCP`. - 2. Para cada controle encontrado, chamar a API PNCP para obter: - - Lista de itens de contratação - - Lista de resultados de cada item - 3. Persistir os dados em duas tabelas distintas no schema `pncp`: - - `pncp.contratacoes_itens` - - `pncp.contratacoes_resultados` - - Observações: - - Cada registro recebe o campo `dt_ingest` com a data/hora da ingestão. - - Conflitos são resolvidos via upsert (`ON CONFLICT`). - """ - - @task - def fetch_and_store_itens_resultados() -> None: - # --- Configuração de clientes --- - api = ClientePNCP() - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - - dt_ingest_iso = datetime.now().isoformat() - - # --- Obter lista de numeroControlePNCP --- - try: - lista_tuplas = db.execute_query( - "SELECT numerocontrolepncp FROM pncp.contratacoes_publicacao" - ) - except Exception as e: - logging.error( - "[pncp_itens_resultados_dag] Erro ao buscar numeroControlePNCP: %s", e - ) - raise - - lista_controles = [t[0] for t in lista_tuplas if t and t[0]] - - logging.info( - "[pncp_itens_resultados_dag] Iniciando coleta | total_controles=%d", - len(lista_controles), - ) - - # --- Coleta na API --- - try: - itens, resultados_brutos = api.get_itens_e_resultados(lista_controles) - # itens_flat = db._flatten_data(itens) - resultados_flat = db._flatten_data(resultados_brutos) - # itens = padronizar_colunas_json(itens_flat) - resultados = padronizar_colunas_json(resultados_flat) - except Exception as e: - logging.error( - "[pncp_itens_resultados_dag] Erro ao coletar dados da API PNCP: %s", e - ) - raise - - # --- Enriquecer com dt_ingest --- - for r in itens: - if isinstance(r, dict): - r["dt_ingest"] = dt_ingest_iso - for r in resultados: - if isinstance(r, dict): - r["dt_ingest"] = dt_ingest_iso - - # --- Persistência --- - if itens: - db.insert_data( - itens, - table_name="contratacoes_itens", - schema="pncp", - conflict_fields=["numeroItem", "numeroControlePNCP"], - primary_key=["numeroItem", "numeroControlePNCP"], - ) - logging.info("[pncp_itens_resultados_dag] Inseridos %d itens.", len(itens)) - else: - logging.warning( - "[pncp_itens_resultados_dag] Nenhum item retornado para inserção." - ) - - if resultados: - db.insert_data( - resultados, - table_name="contratacoes_resultados", - schema="pncp", - conflict_fields=[ - "numeroItem", - "numeroControlePNCPCompra", - "sequencialResultado", - "situacaoCompraItemResultadoId", - ], - primary_key=[ - "numeroItem", - "numeroControlePNCPCompra", - "sequencialResultado", - "situacaoCompraItemResultadoId", - ], - ) - logging.info( - "[pncp_itens_resultados_dag] Inseridos %d resultados.", len(resultados) - ) - else: - logging.warning( - "[pncp_itens_resultados_dag] Nenhum resultado retornado para inserção." - ) - - logging.info("[pncp_itens_resultados_dag] Processo concluído com sucesso.") - - fetch_and_store_itens_resultados() - - -dag_instance = pncp_contratacoes_itens_resultados_dag() diff --git a/dags/data_ingest/pncp/licitacoes_ingest.py b/dags/data_ingest/pncp/licitacoes_ingest.py deleted file mode 100644 index 00f59bc6..00000000 --- a/dags/data_ingest/pncp/licitacoes_ingest.py +++ /dev/null @@ -1,129 +0,0 @@ -import logging -from datetime import datetime, timedelta - -from airflow.decorators import dag, task -from airflow.models import Variable -import yaml - -from postgres_helpers import get_postgres_conn -from cliente_postgres import ClientPostgresDB -from cliente_pncp import ClientePNCP - - -@dag( - schedule_interval="@daily", - start_date=datetime(2024, 12, 4), - catchup=False, - default_args={ - "owner": "Mateus", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["pncp", "compras_publicas"], -) -def pncp_publicacoes_dag() -> None: - """ - DAG para buscar publicações de contratações no PNCP e armazenar no PostgreSQL. - Pega `pncp_codigo_modalidade_contratacao` e `pncp_cnpj` das Airflow Variables. - """ - - @task - def fetch_and_store_pncp_publicacoes() -> None: - - orgao_alvo = Variable.get("airflow_orgao", default_var=None) - if not orgao_alvo: - logging.error("Variável airflow_orgao não definida!") - raise ValueError("airflow_orgao não definida") - - orgaos_config_str = Variable.get("airflow_variables", default_var="{}") - orgaos_config = yaml.safe_load(orgaos_config_str) - - orgao_cfg = orgaos_config.get(orgao_alvo, {}) - cnpj_orgao = orgao_cfg.get("orgao_pncp", []) - modalidades_list = orgao_cfg.get("modalidade_pncp", []) - - try: - cnpj_orgao_int = int(cnpj_orgao) - except ValueError: - logging.error( - "[pncp_publicacoes_dag] Variável pncp_codigo_modalidade_contratacao " - "inválida: %r", - cnpj_orgao, - ) - raise - - end_date = datetime.today() - start_date = end_date - timedelta(weeks=260) - - data_inicial = start_date.strftime("%Y%m%d") - data_final = end_date.strftime("%Y%m%d") - - logging.info( - "[pncp_publicacoes_dag] Iniciando coleta | modalidade=%s | cnpj=%s | " - "janela=[%s, %s]", - modalidades_list, - cnpj_orgao_int, - data_inicial, - data_final, - ) - - # --- Clientes/API e DB --- - api = ClientePNCP() - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - - for cod_modalidade in modalidades_list: - - try: - cod_modalidade_int = int(cod_modalidade) - except ValueError: - logging.error( - "[pncp_publicacoes_dag] Variável pncp_codigo_modalidade_contratacao " - "inválida: %r", - cod_modalidade, - ) - raise - # --- Coleta semestral com paginação interna do cliente --- - registros = api.get_contratacoes_publicacao_semestral( - data_inicial=data_inicial, - data_final=data_final, - codigo_modalidade_contratacao=cod_modalidade_int, - cnpj=cnpj_orgao_int, - ) - - if not registros: - logging.warning( - "[pncp_publicacoes_dag] Nenhum registro retornado do PNCP." - ) - pass - - # Enriquecer com dt_ingest - dt_ingest_iso = datetime.now().isoformat() - for r in registros: - # garante que é dict antes de setar a chave - if isinstance(r, dict): - r["dt_ingest"] = dt_ingest_iso - - # --- Persistência --- - logging.info( - "[pncp_publicacoes_dag] Inserindo %s registros no schema " - "pncp.tabela=contratacoes_publicacao", - len(registros), - ) - - # Se você conhecer a(s) PK(s) de fato, preencha em - # primary_key/conflict_fields. - db.insert_data( - registros, - table_name="contratacoes_publicacao", - conflict_fields=["numeroControlePNCP"], - primary_key=["numeroControlePNCP"], - schema="pncp", - ) - - logging.info("[pncp_publicacoes_dag] Inserção concluída com sucesso.") - - fetch_and_store_pncp_publicacoes() - - -dag_instance = pncp_publicacoes_dag() diff --git a/dags/data_ingest/sgac/projetos_sgac_ingest_dag.py b/dags/data_ingest/sgac/projetos_sgac_ingest_dag.py deleted file mode 100644 index 38e1c95f..00000000 --- a/dags/data_ingest/sgac/projetos_sgac_ingest_dag.py +++ /dev/null @@ -1,203 +0,0 @@ -from typing import Dict, Any, Optional -from airflow import DAG -from airflow.operators.python import PythonOperator -from airflow.models import Variable -from datetime import datetime, timedelta -import logging -import json -from schedule_loader import get_dynamic_schedule -from cliente_email import fetch_and_process_email_csv_attachment -from cliente_postgres import ClientPostgresDB -from postgres_helpers import get_postgres_conn -import pandas as pd -import io - -# Configurações básicas da DAG -default_args = { - "owner": "Wallyson", - "depends_on_past": False, - "retries": 1, - "retry_delay": timedelta(minutes=5), -} - -COLUMN_MAPPING = { - 0: "odata_etag", - 1: "id_interno_item", - 2: "id", - 3: "titulo", - 4: "entidades_externas", - 5: "instrumento", - 6: "instrumento_id", - 7: "diretoria_responsavel", - 8: "diretoria_responsavel_id", - 9: "objeto", - 10: "data_inicio", - 11: "data_vencimento", - 12: "total_de_recursos", - 13: "numero_do_proc", - 14: "coordenador", - 15: "coordenador_tipo_odata", - 16: "coordenador_claims", - 17: "coordenador_claims_tipo_odata", - 18: "nacionalidade", - 19: "nacionalidade_tipo_odata", - 20: "nacionalidade_id", - 21: "nacionalidade_id_tipo_odata", - 22: "recursos_orcament_x00", - 23: "recursos_orcament_x0", - 24: "status", - 25: "status_id", - 26: "eixo_tematico", - 27: "eixo_tematico_tipo_odata", - 28: "eixo_tematico_id", - 29: "eixo_tematico_id_tipo_odata", - 30: "predecessores", - 31: "predecessores_tipo_odata", - 32: "predecessores_id", - 33: "predecessores_id_tipo_odata", - 34: "prioridade", - 35: "prioridade_id", - 36: "justificativa", - 37: "objetivo_s_ge", - 38: "equipe_tecnica", - 39: "equipe_tecnica_tipo_odata", - 40: "equipe_tecnica_claims", - 41: "equipe_tecnica_claims_tipo_odata", - 42: "codigo", - 43: "unidades_envolvidas", - 44: "unidades_envolvidas_tipo_odata", - 45: "unidades_envolvidas_id", - 46: "unidades_envolvidas_id_tipo_odata", - 47: "historico_observa_x0", - 48: "a_solicitacao", - 49: "a_solicitacao_tipo_odata", - 50: "a_solicitacao_id", - 51: "a_solicitacao_id_tipo_odata", - 52: "modificado", - 53: "criado", - 54: "autor", - 55: "autor_claims", - 56: "editor", - 57: "editor_claims", - 58: "identificador", - 59: "eh_pasta", - 60: "miniatura", - 61: "link", - 62: "nome", - 63: "nome_arquivo_com_extensao", - 64: "caminho", - 65: "caminho_completo", - 66: "tipo_conteudo", - 67: "tipo_conteudo_id", - 68: "possui_anexos", - 69: "numero_versao", - 70: "aprovacao", - 71: "termos_aditivos", - 72: "equipe", - 73: "percentual_concluido", - 74: "corpo", - 75: "fiscal_e_substituto", - 76: "numero_siafi", - 77: "atribuido_a", - 78: "atribuido_a_claims" -} - -EMAIL_SUBJECT = "SGAC" -SKIPROWS = 1 - -# Configurações da DAG -with DAG( - dag_id="email_projetos_sgac_ingest", - default_args=default_args, - description="Processa anexos do email de dados do SGAC e insere no db", - schedule_interval=get_dynamic_schedule("email_projetos_sgac_ingest"), - start_date=datetime(2023, 12, 1), - catchup=False, - tags=["email", "projetos", "sgac"], -) as dag: - - def process_email_data(**context: Dict[str, Any]) -> Optional[Any]: - creds = json.loads(Variable.get("email_credentials")) - - EMAIL = creds["email"] - PASSWORD = creds["password"] - IMAP_SERVER = creds["imap_server"] - SENDER_EMAIL = Variable.get("sender_email_sgac", default_var=creds["sender_email"],) - - try: - logging.info("Iniciando o processamento dos emails...") - csv_data = fetch_and_process_email_csv_attachment( - IMAP_SERVER, - EMAIL, - PASSWORD, - SENDER_EMAIL, - EMAIL_SUBJECT, - COLUMN_MAPPING, - skiprows=SKIPROWS, - ) - if not csv_data: - logging.warning("Nenhum e-mail encontrado com o assunto esperado.") - return None - - total_linhas = max(len(csv_data.splitlines()) - 1, 0) - logging.info( - "CSV processado com sucesso. Dados encontrados: %s", total_linhas - ) - return csv_data - except Exception as e: - logging.error("Erro no processamento dos emails: %s", str(e)) - raise - - def insert_data_to_db(**context: Dict[str, Any]) -> None: - """Insere no Postgres os dados retornados pela task de processamento do e-mail.""" - try: - task_instance: Any = context["ti"] - csv_data: Any = task_instance.xcom_pull(task_ids="process_emails") - - if not csv_data: - logging.warning("Nenhum dado para inserir no banco.") - return - - df = pd.read_csv(io.StringIO(csv_data)) - if df.empty: - logging.warning("CSV recebido sem registros para insercao.") - return - - data = df.to_dict(orient="records") - # Adiciona timestamp de ingestão a cada registro - for record in data: - record["dt_ingest"] = datetime.now().isoformat() - - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - - unique_key = ["id"] - - db.insert_data( - data, - "projetos_sgac", - conflict_fields=unique_key, - primary_key=unique_key, - schema="sgac", - ) - logging.info("Dados inseridos com sucesso no banco de dados.") - except Exception as e: - logging.error("Erro ao inserir dados no banco: %s", str(e)) - raise - - #tarefa 1: processar os e-mails e extrair o CSV - process_emails_task = PythonOperator( - task_id="process_emails", - python_callable=process_email_data, - provide_context=True, - ) - #tarefa 2: inserir os dados no banco de dados - insert_to_db_task = PythonOperator( - task_id="insert_to_db", - python_callable=insert_data_to_db, - provide_context=True, - ) - #Fluxo da DAG - process_emails_task >> insert_to_db_task - - \ No newline at end of file diff --git a/dags/data_ingest/siafi/nota_credito_siafi_ingest_dag.py b/dags/data_ingest/siafi/nota_credito_siafi_ingest_dag.py deleted file mode 100644 index 242fe379..00000000 --- a/dags/data_ingest/siafi/nota_credito_siafi_ingest_dag.py +++ /dev/null @@ -1,59 +0,0 @@ -from airflow.decorators import dag, task -from datetime import datetime, timedelta -from schedule_loader import get_dynamic_schedule -from cliente_siafi import ClienteSiafi -from cliente_postgres import ClientPostgresDB -from postgres_helpers import get_postgres_conn - - -@dag( - schedule_interval=get_dynamic_schedule("nota_credito_siafi_ingest_dag"), - start_date=datetime(2024, 3, 12), - catchup=False, - default_args={ - "owner": "Davi", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["nota_credito", "siafi_api"], -) -def nota_credito_siafi_dag() -> None: - @task - def fetch_and_store_nota_credito() -> None: - cliente_siafi = ClienteSiafi() - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - notas_credito = db.get_nota_credito() - - for nota_credito in notas_credito: - cd_ug_emitente_nota = nota_credito[0] - cd_gestao_emitente_nota = nota_credito[1] - tx_numero_nota = nota_credito[2] - - if not all([cd_ug_emitente_nota, cd_gestao_emitente_nota, tx_numero_nota]): - continue - - ano = tx_numero_nota[:4] - numero = tx_numero_nota[-6:] - - response = cliente_siafi.consultar_nota_credito( - ug=cd_ug_emitente_nota, - gestao=cd_gestao_emitente_nota, - ano=ano, - numero=numero, - ) - if response: - response["ano"] = ano - response["dt_ingest"] = datetime.now().isoformat() - db.insert_data( - [response], - "nota_credito", - conflict_fields=["numero", "ano"], - primary_key=["numero", "ano"], - schema="siafi", - ) - - fetch_and_store_nota_credito() - - -dag_instance = nota_credito_siafi_dag() diff --git a/dags/data_ingest/siafi/nota_empenho_siafi_ingest_dag.py b/dags/data_ingest/siafi/nota_empenho_siafi_ingest_dag.py deleted file mode 100644 index 32a9668a..00000000 --- a/dags/data_ingest/siafi/nota_empenho_siafi_ingest_dag.py +++ /dev/null @@ -1,93 +0,0 @@ -import logging -import yaml -from airflow.decorators import dag, task -from airflow.models import Variable -from airflow.models.param import Param -from datetime import datetime, timedelta -from typing import Dict, Any -from schedule_loader import get_dynamic_schedule -from cliente_siafi import ClienteSiafi -from cliente_postgres import ClientPostgresDB -from postgres_helpers import get_postgres_conn - - -@dag( - schedule_interval=get_dynamic_schedule("nota_empenho_siafi_ingest_dag"), - start_date=datetime(2023, 3, 17), - catchup=False, - default_args={ - "owner": "Davi", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - params={ - "ano_inicio": Param( - default=None, - type=["integer", "null"], - title="Ano de Início", - description="Backfill: Ano inicio para busca de notas de empenho. (type=int)", - ), - "ano_fim": Param( - default=None, - type=["integer", "null"], - title="Ano de Fim", - description="Backfill: Ano final para busca de notas de empenho. (type=int)", - ), - }, - tags=["nota_empenho", "siafi_api"], -) -def nota_empenho_siafi_ingest_dag() -> None: - @task - def fetch_and_store_notas_empenho(**context: Dict[str, Any]) -> None: - logging.info("Iniciando fetch_and_store_notas_empenho") - - orgao_alvo = Variable.get("airflow_orgao", default_var=None) - if not orgao_alvo: - logging.error("Variável airflow_orgao não definida!") - raise ValueError("airflow_orgao não definida") - - orgaos_config_str = Variable.get("airflow_variables", default_var="{}") - orgaos_config = yaml.safe_load(orgaos_config_str) - - ugs_emitentes = orgaos_config.get(orgao_alvo, {}).get("codigos_ug", []) - - if not ugs_emitentes: - logging.warning(f"Nenhum código UG encontrado para o órgão '{orgao_alvo}'") - return - - cliente = ClienteSiafi() - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - - params = context["params"] - ano_inicio = params.get("ano_inicio") - ano_fim = params.get("ano_fim") - - ano_atual = datetime.now().year - ano_inicio = ano_inicio or ano_atual - ano_fim = ano_fim or ano_atual - - anos_consulta = list(range(ano_inicio, ano_fim + 1)) - - for ug in ugs_emitentes: - for ano in anos_consulta: - num_empenho = 1 - while True: - num_empenho_str = str(num_empenho).zfill(6) - resultado = cliente.consultar_nota_empenho(ug, ano, num_empenho_str) - if not resultado: - break - resultado["dt_ingest"] = datetime.now().isoformat() - db.insert_data( - [resultado], - "notas_empenho", - conflict_fields=["numEmpenho", "anoEmpenho"], - primary_key=["numEmpenho", "anoEmpenho"], - schema="siafi", - ) - num_empenho += 1 - - fetch_and_store_notas_empenho() - - -dag_instance = nota_empenho_siafi_ingest_dag() diff --git a/dags/data_ingest/siafi/programacao_financeira_siafi_ingest_dag.py b/dags/data_ingest/siafi/programacao_financeira_siafi_ingest_dag.py deleted file mode 100644 index 4c277135..00000000 --- a/dags/data_ingest/siafi/programacao_financeira_siafi_ingest_dag.py +++ /dev/null @@ -1,50 +0,0 @@ -from airflow.decorators import dag, task -from datetime import datetime, timedelta -from schedule_loader import get_dynamic_schedule -from cliente_siafi import ClienteSiafi -from cliente_postgres import ClientPostgresDB -from postgres_helpers import get_postgres_conn - - -@dag( - schedule_interval=get_dynamic_schedule("programacao_financeira_siafi_ingest_dag"), - start_date=datetime(2024, 3, 12), - catchup=False, - default_args={ - "owner": "Davi", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["programacao_financeira", "siafi_api"], -) -def programacao_financeira_siafi_dag() -> None: - @task - def fetch_and_store_programacao_financeira() -> None: - cliente_siafi = ClienteSiafi() - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - programacoes = db.get_programacao_financeira() - - for programacao in programacoes: - tx_numero_programacao, ug_emitente_programacao = programacao - ano = int(str(tx_numero_programacao)[:4]) - num_lista = int(str(tx_numero_programacao)[-6:]) - ug_emitente = int(ug_emitente_programacao) - - response = cliente_siafi.consultar_programacao_financeira( - ug_emitente, ano, num_lista - ) - if response: - response["dt_ingest"] = datetime.now().isoformat() - db.insert_data( - [response], - "programacao_financeira_siafi", - conflict_fields=["TRF__numeroDocumento"], - primary_key=["TRF__numeroDocumento"], - schema="siafi", - ) - - fetch_and_store_programacao_financeira() - - -dag_instance = programacao_financeira_siafi_dag() diff --git a/dags/data_ingest/siape/dados_afastamento_historico_siape_ingest_dag.py b/dags/data_ingest/siape/dados_afastamento_historico_siape_ingest_dag.py deleted file mode 100644 index 290cb179..00000000 --- a/dags/data_ingest/siape/dados_afastamento_historico_siape_ingest_dag.py +++ /dev/null @@ -1,95 +0,0 @@ -import os -import logging -from datetime import datetime, timedelta -from airflow.decorators import dag, task -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_siape import ClienteSiape -from cliente_postgres import ClientPostgresDB - - -@dag( - schedule_interval=get_dynamic_schedule( - "dados_afastamento_historico_siape_ingest_dag" - ), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "owner": "Joyce", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["siape", "afastamento_historico"], -) -def siape_afastamento_historico_dag() -> None: - """ - DAG que consome o endpoint consultaDadosAfastamentoHistorico da API SIAPE - e armazena os dados de afastamentos antigos dos servidores no schema 'siape'. - """ - - @task - def fetch_and_store_afastamento_historico() -> None: - logging.info("Iniciando extração de dados de afastamento histórico por CPF") - cliente_siape = ClienteSiape() - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - - query = "SELECT DISTINCT cpf FROM siape.lista_servidores WHERE cpf IS NOT NULL" - cpfs = [row[0] for row in db.execute_query(query)] - logging.info(f"Total de CPFs encontrados: {len(cpfs)}") - - for cpf in cpfs: - try: - context = { - "siglaSistema": "PETRVS-IPEA", - "nomeSistema": "PDG-PETRVS-IPEA", - "senha": os.getenv("SIAPE_PASSWORD_USER"), - "cpf": cpf, - "codOrgao": "45206", - "parmExistPag": "b", - "parmTipoVinculo": "c", - "anoInicial": "2024", - "mesInicial": "01", - "anoFinal": "2025", - "mesFinal": "12", - } - - resposta_xml = cliente_siape.call( - "consultaDadosAfastamentoHistorico.xml.j2", context - ) - - dados = ClienteSiape.parse_afastamento_historico(resposta_xml) - - if not dados: - logging.info(f"Nenhum dado de afastamento histórico para CPF {cpf}") - continue - - for row in dados: - row["cpf"] = cpf - row["dt_ingest"] = datetime.now().isoformat() - - if dados: - db.alter_table( - data=dados[0], - table_name="afastamento_historico", - schema="siape", - ) - - db.insert_data( - dados, - table_name="afastamento_historico", - conflict_fields=None, - primary_key=None, - schema="siape", - ) - - logging.info(f"{len(dados)} registros inseridos para CPF {cpf}") - - except Exception as e: - logging.error(f"Erro ao processar CPF {cpf}: {e}") - continue - - fetch_and_store_afastamento_historico() - - -dag_instance = siape_afastamento_historico_dag() diff --git a/dags/data_ingest/siape/dados_afastamento_siape_ingest_dag.py b/dags/data_ingest/siape/dados_afastamento_siape_ingest_dag.py deleted file mode 100644 index 46acd096..00000000 --- a/dags/data_ingest/siape/dados_afastamento_siape_ingest_dag.py +++ /dev/null @@ -1,87 +0,0 @@ -import os -import logging -from datetime import datetime, timedelta -from airflow.decorators import dag, task -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_siape import ClienteSiape -from cliente_postgres import ClientPostgresDB - - -@dag( - schedule_interval=get_dynamic_schedule("dados_afastamento_siape_ingest_dag"), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "owner": "Joyce", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["siape", "dados_afastamento"], -) -def siape_dados_afastamento_dag() -> None: - """ - DAG que consome o endpoint consultaDadosAfastamento da API SIAPE - e armazena dados de afastamento atuais no schema 'siape'. - """ - - @task - def fetch_and_store_dados_afastamento() -> None: - logging.info("Iniciando extração de dados de afastamento por CPF") - cliente_siape = ClienteSiape() - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - - query = "SELECT DISTINCT cpf FROM siape.lista_servidores WHERE cpf IS NOT NULL" - cpfs = [row[0] for row in db.execute_query(query)] - logging.info(f"Total de CPFs encontrados: {len(cpfs)}") - - for cpf in cpfs: - try: - context = { - "siglaSistema": "PETRVS-IPEA", - "nomeSistema": "PDG-PETRVS-IPEA", - "senha": os.getenv("SIAPE_PASSWORD_USER"), - "cpf": cpf, - "codOrgao": "45206", - "parmExistPag": "b", - "parmTipoVinculo": "c", - } - - resposta_xml = cliente_siape.call( - "consultaDadosAfastamento.xml.j2", context - ) - dados = ClienteSiape.parse_xml_to_dict(resposta_xml) - - if not dados: - logging.warning(f"Nenhum dado de afastamento para CPF {cpf}") - continue - - dados["cpf"] = cpf - dados["dt_ingest"] = datetime.now().isoformat() - - if dados: - db.alter_table( - data=dados, - table_name="dados_afastamento", - schema="siape", - ) - - db.insert_data( - [dados], - table_name="dados_afastamento", - conflict_fields=["cpf"], - primary_key=["cpf"], - schema="siape", - ) - - logging.info(f"Dado de afastamento inserido para CPF {cpf}") - - except Exception as e: - logging.error(f"Erro ao processar CPF {cpf}: {e}") - continue - - fetch_and_store_dados_afastamento() - - -dag_instance = siape_dados_afastamento_dag() diff --git a/dags/data_ingest/siape/dados_curriculo_siape_ingest_dag.py b/dags/data_ingest/siape/dados_curriculo_siape_ingest_dag.py deleted file mode 100644 index ab8fcde2..00000000 --- a/dags/data_ingest/siape/dados_curriculo_siape_ingest_dag.py +++ /dev/null @@ -1,85 +0,0 @@ -import os -import logging -from datetime import datetime, timedelta -from airflow.decorators import dag, task -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_siape import ClienteSiape -from cliente_postgres import ClientPostgresDB - - -@dag( - schedule_interval=get_dynamic_schedule("dados_curriculo_siape_ingest_dag"), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "owner": "Joyce", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["siape", "dados_curriculo"], -) -def siape_dados_curriculo_dag() -> None: - """ - DAG que consome o endpoint consultaDadosCurriculo da API SIAPE - e armazena os dados de currículo dos servidores no schema 'siape'. - """ - - @task - def fetch_and_store_dados_curriculo() -> None: - logging.info("Iniciando extração de dados de currículo por CPF") - cliente_siape = ClienteSiape() - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - - query = "SELECT DISTINCT cpf FROM siape.lista_servidores WHERE cpf IS NOT NULL" - cpfs = [row[0] for row in db.execute_query(query)] - logging.info(f"Total de CPFs encontrados: {len(cpfs)}") - - for cpf in cpfs: - try: - context = { - "siglaSistema": "PETRVS-IPEA", - "nomeSistema": "PDG-PETRVS-IPEA", - "senha": os.getenv("SIAPE_PASSWORD_USER"), - "cpf": cpf, - "codOrgao": "45206", - "parmExistPag": "b", - "parmTipoVinculo": "c", - } - - resposta_xml = cliente_siape.call( - "consultaDadosCurriculo.xml.j2", context - ) - dados = ClienteSiape.parse_xml_to_dict(resposta_xml) - - if not dados: - logging.warning(f"Nenhum dado de currículo encontrado para CPF {cpf}") - continue - - dados["dt_ingest"] = datetime.now().isoformat() - - db.alter_table( - data=dados, - table_name="dados_curriculo", - schema="siape", - ) - - db.insert_data( - [dados], - table_name="dados_curriculo", - conflict_fields=["cpf"], - primary_key=["cpf"], - schema="siape", - ) - - logging.info(f"Dado de currículo inserido para CPF {cpf}") - - except Exception as e: - logging.error(f"Erro ao processar CPF {cpf}: {e}") - continue - - fetch_and_store_dados_curriculo() - - -dag_instance = siape_dados_curriculo_dag() diff --git a/dags/data_ingest/siape/dados_dependentes_siape_ingest_dag.py b/dags/data_ingest/siape/dados_dependentes_siape_ingest_dag.py deleted file mode 100644 index dc198bc1..00000000 --- a/dags/data_ingest/siape/dados_dependentes_siape_ingest_dag.py +++ /dev/null @@ -1,87 +0,0 @@ -import os -import logging -from datetime import datetime, timedelta -from airflow.decorators import dag, task -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_siape import ClienteSiape -from cliente_postgres import ClientPostgresDB - - -@dag( - schedule_interval=get_dynamic_schedule("dados_dependentes_siape_ingest_dag"), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "owner": "Joyce", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["siape", "dados_dependentes"], -) -def siape_dados_dependentes_dag() -> None: - """ - DAG que consome o endpoint consultaDadosDependentes da API SIAPE - e armazena os dados de dependentes dos servidores no schema 'siape'. - """ - - @task - def fetch_and_store_dados_dependentes() -> None: - logging.info("Iniciando extração de dados de dependentes por CPF") - cliente_siape = ClienteSiape() - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - - query = "SELECT DISTINCT cpf FROM siape.lista_servidores WHERE cpf IS NOT NULL" - cpfs = [row[0] for row in db.execute_query(query)] - logging.info(f"Total de CPFs encontrados: {len(cpfs)}") - - for cpf in cpfs: - try: - context = { - "siglaSistema": "PETRVS-IPEA", - "nomeSistema": "PDG-PETRVS-IPEA", - "senha": os.getenv("SIAPE_PASSWORD_USER"), - "cpf": cpf, - "codOrgao": "45206", - "parmExistPag": "b", - "parmTipoVinculo": "c", - } - - resposta_xml = cliente_siape.call( - "consultaDadosDependentes.xml.j2", context - ) - dados = ClienteSiape.parse_dependentes(resposta_xml) - - if not dados: - logging.warning(f"Nenhum dependente encontrado para CPF {cpf}") - continue - - for row in dados: - row["cpf"] = cpf - row["dt_ingest"] = datetime.now().isoformat() - - db.alter_table( - data=dados[0], - table_name="dados_dependentes", - schema="siape", - ) - - db.insert_data( - dados, - table_name="dados_dependentes", - conflict_fields=["cpf", "nome"], - primary_key=["cpf", "nome"], - schema="siape", - ) - - logging.info(f"{len(dados)} dependente(s) inserido(s) para CPF {cpf}") - - except Exception as e: - logging.error(f"Erro ao processar CPF {cpf}: {e}") - continue - - fetch_and_store_dados_dependentes() - - -dag_instance = siape_dados_dependentes_dag() diff --git a/dags/data_ingest/siape/dados_escolares_siape_ingest_dag.py b/dags/data_ingest/siape/dados_escolares_siape_ingest_dag.py deleted file mode 100644 index 09912607..00000000 --- a/dags/data_ingest/siape/dados_escolares_siape_ingest_dag.py +++ /dev/null @@ -1,86 +0,0 @@ -import os -import logging -from datetime import datetime, timedelta -from airflow.decorators import dag, task -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_siape import ClienteSiape -from cliente_postgres import ClientPostgresDB - - -@dag( - schedule_interval=get_dynamic_schedule("dados_escolares_siape_ingest_dag"), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "owner": "Joyce", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["siape", "dados_escolares"], -) -def siape_dados_escolares_dag() -> None: - """ - DAG que consome o endpoint consultaDadosEscolares da API SIAPE - e armazena os dados de escolaridade dos servidores no schema 'siape'. - """ - - @task - def fetch_and_store_dados_escolares() -> None: - logging.info("Iniciando extração de dados escolares por CPF") - cliente_siape = ClienteSiape() - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - - query = "SELECT DISTINCT cpf FROM siape.lista_servidores WHERE cpf IS NOT NULL" - cpfs = [row[0] for row in db.execute_query(query)] - logging.info(f"Total de CPFs encontrados: {len(cpfs)}") - - for cpf in cpfs: - try: - context = { - "siglaSistema": "PETRVS-IPEA", - "nomeSistema": "PDG-PETRVS-IPEA", - "senha": os.getenv("SIAPE_PASSWORD_USER"), - "cpf": cpf, - "codOrgao": "45206", - "parmExistPag": "b", - "parmTipoVinculo": "c", - } - - resposta_xml = cliente_siape.call( - "consultaDadosEscolares.xml.j2", context - ) - dados = ClienteSiape.parse_xml_to_dict(resposta_xml) - - if not dados: - logging.warning(f"Nenhum dado escolar encontrado para CPF {cpf}") - continue - - dados["cpf"] = cpf - dados["dt_ingest"] = datetime.now().isoformat() - - db.alter_table( - data=dados, - table_name="dados_escolares", - schema="siape", - ) - - db.insert_data( - [dados], - table_name="dados_escolares", - conflict_fields=["cpf"], - primary_key=["cpf"], - schema="siape", - ) - - logging.info(f"Dado escolar inserido para CPF {cpf}") - - except Exception as e: - logging.error(f"Erro ao processar CPF {cpf}: {e}") - continue - - fetch_and_store_dados_escolares() - - -dag_instance = siape_dados_escolares_dag() diff --git a/dags/data_ingest/siape/dados_financeiros_siape_dag.py b/dags/data_ingest/siape/dados_financeiros_siape_dag.py deleted file mode 100644 index cc20626b..00000000 --- a/dags/data_ingest/siape/dados_financeiros_siape_dag.py +++ /dev/null @@ -1,86 +0,0 @@ -import os -import logging -from datetime import datetime, timedelta -from airflow.decorators import dag, task -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_siape import ClienteSiape -from cliente_postgres import ClientPostgresDB - - -@dag( - schedule_interval=get_dynamic_schedule("dados_financeiros_siape_dag"), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "owner": "Joyce", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["siape", "dados_financeiros"], -) -def siape_dados_financeiros_dag() -> None: - """ - DAG que consome o endpoint consultaDadosFinanceiros da API SIAPE - e armazena os dados financeiros dos servidores no schema 'siape'. - """ - - @task - def fetch_and_store_dados_financeiros() -> None: - logging.info("Iniciando extração de dados financeiros por CPF") - cliente_siape = ClienteSiape() - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - - query = "SELECT DISTINCT cpf FROM siape.lista_servidores WHERE cpf IS NOT NULL" - cpfs = [row[0] for row in db.execute_query(query)] - logging.info(f"Total de CPFs encontrados: {len(cpfs)}") - - for cpf in cpfs: - try: - context = { - "siglaSistema": "PETRVS-IPEA", - "nomeSistema": "PDG-PETRVS-IPEA", - "senha": os.getenv("SIAPE_PASSWORD_USER"), - "cpf": cpf, - "codOrgao": "45206", - "parmExistPag": "b", - "parmTipoVinculo": "c", - } - - resposta_xml = cliente_siape.call( - "consultaDadosFinanceiros.xml.j2", context - ) - dados = ClienteSiape.parse_xml_to_dict(resposta_xml) - - if not dados: - logging.warning(f"Nenhum dado financeiro encontrado para CPF {cpf}") - continue - - dados["cpf"] = cpf - dados["dt_ingest"] = datetime.now().isoformat() - - db.alter_table( - data=dados, - table_name="dados_financeiros", - schema="siape", - ) - - db.insert_data( - [dados], - table_name="dados_financeiros", - conflict_fields=["cpf"], - primary_key=["cpf"], - schema="siape", - ) - - logging.info(f"Dado financeiro inserido para CPF {cpf}") - - except Exception as e: - logging.error(f"Erro ao processar CPF {cpf}: {e}") - continue - - fetch_and_store_dados_financeiros() - - -dag_instance = siape_dados_financeiros_dag() diff --git a/dags/data_ingest/siape/dados_funcionais_siape_ingest_dag.py b/dags/data_ingest/siape/dados_funcionais_siape_ingest_dag.py deleted file mode 100644 index 8d5485a8..00000000 --- a/dags/data_ingest/siape/dados_funcionais_siape_ingest_dag.py +++ /dev/null @@ -1,82 +0,0 @@ -import os -import logging -from datetime import datetime, timedelta -from airflow.decorators import dag, task -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_siape import ClienteSiape -from cliente_postgres import ClientPostgresDB - - -@dag( - schedule_interval=get_dynamic_schedule("dados_funcionais_siape_ingest_dag"), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "owner": "Joyce", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["siape", "dados_funcionais"], -) -def siape_dados_funcionais_dag() -> None: - - @task - def fetch_and_store_dados_funcionais() -> None: - logging.info("Iniciando extração de dados funcionais por CPF") - cliente_siape = ClienteSiape() - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - - query = "SELECT DISTINCT cpf FROM siape.lista_servidores WHERE cpf IS NOT NULL" - cpfs = [row[0] for row in db.execute_query(query)] - logging.info(f"Total de CPFs encontrados: {len(cpfs)}") - - for cpf in cpfs: - try: - context = { - "siglaSistema": "PETRVS-IPEA", - "nomeSistema": "PDG-PETRVS-IPEA", - "senha": os.getenv("SIAPE_PASSWORD_USER"), - "cpf": cpf, - "codOrgao": "45206", - "parmExistPag": "b", - "parmTipoVinculo": "c", - } - - resposta_xml = cliente_siape.call( - "consultaDadosFuncionais.xml.j2", context - ) - dados = ClienteSiape.parse_dado_funcional(resposta_xml) - - if not dados: - logging.warning(f"Nenhum dado funcional encontrado para CPF {cpf}") - continue - - dados["cpf"] = cpf - dados["dt_ingest"] = datetime.now().isoformat() - - db.alter_table( - data=dados, - table_name="dados_funcionais", - schema="siape", - ) - - db.insert_data( - [dados], - table_name="dados_funcionais", - conflict_fields=["cpf"], - primary_key=["cpf"], - schema="siape", - ) - - logging.info(f"Dado funcional inserido para CPF {cpf}") - - except Exception as e: - logging.error(f"Erro ao processar CPF {cpf}: {e}") - continue - - fetch_and_store_dados_funcionais() - - -dag_instance = siape_dados_funcionais_dag() diff --git a/dags/data_ingest/siape/dados_pa_siape_ingest_dag.py b/dags/data_ingest/siape/dados_pa_siape_ingest_dag.py deleted file mode 100644 index 4fb35850..00000000 --- a/dags/data_ingest/siape/dados_pa_siape_ingest_dag.py +++ /dev/null @@ -1,121 +0,0 @@ -import os -import logging -from datetime import datetime, timedelta -from airflow.decorators import dag, task -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_siape import ClienteSiape -from cliente_postgres import ClientPostgresDB - - -@dag( - schedule_interval=get_dynamic_schedule("dados_pa_siape_ingest_dag"), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "owner": "Joyce", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["siape", "dados_pa"], -) -def siape_dados_pa_dag() -> None: - """ - DAG que consome o endpoint consultaDadosPA da API SIAPE - e armazena o plano de atuação dos servidores no schema 'siape'. - """ - - @task - def fetch_and_store_dados_pa() -> None: - logging.info("Iniciando extração de dados de plano de atuação por CPF") - cliente_siape = ClienteSiape() - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - - # Garante que schema, tabela e chave primária existam - ddl = """ - DO $$ - BEGIN - IF NOT EXISTS ( - SELECT 1 FROM information_schema.schemata WHERE schema_name = 'siape' - ) THEN - EXECUTE 'CREATE SCHEMA siape'; - END IF; - - IF NOT EXISTS ( - SELECT 1 FROM information_schema.tables - WHERE table_schema = 'siape' AND table_name = 'dados_pa' - ) THEN - EXECUTE ' - CREATE TABLE siape.dados_pa ( - cpf_servidor TEXT PRIMARY KEY - ) - '; - END IF; - - IF NOT EXISTS ( - SELECT 1 FROM information_schema.table_constraints - WHERE table_schema = 'siape' - AND table_name = 'dados_pa' - AND constraint_type = 'PRIMARY KEY' - ) THEN - EXECUTE 'ALTER TABLE siape.dados_pa ADD CONSTRAINT dados_pa_pkey ' || - 'PRIMARY KEY (cpf_servidor)'; - END IF; - END - $$; - """ - db.execute_non_query(ddl) # Assumindo que esse método executa sem fetch - logging.info("Estrutura da tabela verificada/criada com sucesso.") - - query = "SELECT DISTINCT cpf FROM siape.lista_servidores WHERE cpf IS NOT NULL" - cpfs = [row[0] for row in db.execute_query(query)] - logging.info(f"Total de CPFs encontrados: {len(cpfs)}") - - for cpf in cpfs: - try: - logging.info(f"Processando CPF: {cpf}") - context = { - "siglaSistema": "PETRVS-IPEA", - "nomeSistema": "PDG-PETRVS-IPEA", - "senha": os.getenv("SIAPE_PASSWORD_USER"), - "cpf": cpf, - "codOrgao": "45206", - "parmExistPag": "b", - "parmTipoVinculo": "c", - } - - resposta_xml = cliente_siape.call("consultaDadosPA.xml.j2", context) - dados = ClienteSiape.parse_xml_to_dict(resposta_xml) - - if not dados: - logging.warning(f"Nenhum dado PA encontrado para CPF {cpf}") - continue - - dados["cpf_servidor"] = cpf - dados["dt_ingest"] = datetime.now().isoformat() - - db.alter_table( - data=dados, - table_name="dados_pa", - schema="siape", - ) - - db.insert_data( - [dados], - table_name="dados_pa", - conflict_fields=["cpf_servidor"], - primary_key=["cpf_servidor"], - schema="siape", - ) - - logging.info(f"Plano de atuação inserido para CPF {cpf}") - - except Exception as e: - logging.error(f"Erro ao processar CPF {cpf}: {e}", exc_info=True) - continue - - fetch_and_store_dados_pa() - - -dag_instance = siape_dados_pa_dag() diff --git a/dags/data_ingest/siape/dados_pessoais_siape_ingest_dag.py b/dags/data_ingest/siape/dados_pessoais_siape_ingest_dag.py deleted file mode 100644 index d8447e5e..00000000 --- a/dags/data_ingest/siape/dados_pessoais_siape_ingest_dag.py +++ /dev/null @@ -1,141 +0,0 @@ -import os -import logging -from datetime import datetime, timedelta -from airflow.decorators import dag, task -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_siape import ClienteSiape -from cliente_postgres import ClientPostgresDB - - -@dag( - schedule_interval=get_dynamic_schedule("dados_pessoais_siape_ingest_dag"), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "owner": "Joyce", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["siape", "dados_pessoais"], -) -def siape_dados_pessoais_dag() -> None: - """ - DAG que consome o endpoint consultaDadosPessoais da API SIAPE - e armazena os dados pessoais de servidores públicos no schema 'siape'. - """ - - @task - def fetch_and_store_dados_pessoais() -> None: - logging.info("Iniciando extração de dados pessoais por CPF") - cliente_siape = ClienteSiape() - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - - # --- Garantia de schema, tabela e PRIMARY KEY --- - logging.info("Verificando existência da tabela e constraint PRIMARY KEY") - ddl = """ - DO $$ - BEGIN - -- Cria schema se não existir - IF NOT EXISTS ( - SELECT 1 FROM information_schema.schemata WHERE schema_name = 'siape' - ) THEN - EXECUTE 'CREATE SCHEMA siape'; - END IF; - - -- Cria tabela se não existir - IF NOT EXISTS ( - SELECT 1 FROM information_schema.tables - WHERE table_schema = 'siape' AND table_name = 'dados_pessoais' - ) THEN - EXECUTE ' - CREATE TABLE siape.dados_pessoais ( - cpf TEXT PRIMARY KEY -- Define cpf como PK já na criação - ) - '; - END IF; - - -- Adiciona PK se a tabela existe mas ainda não tem - IF NOT EXISTS ( - SELECT 1 FROM information_schema.table_constraints - WHERE table_schema = 'siape' - AND table_name = 'dados_pessoais' - AND constraint_type = 'PRIMARY KEY' - ) THEN - EXECUTE ( - 'ALTER TABLE siape.dados_pessoais ADD CONSTRAINT dados_pessoais_pkey ' - 'PRIMARY KEY (cpf)' - ); - END IF; - END - $$; - """ - db.execute_non_query(ddl) - logging.info("Estrutura da tabela verificada/criada com sucesso.") - - # --- Continua fluxo normal --- - query = "SELECT DISTINCT cpf FROM siape.lista_servidores WHERE cpf IS NOT NULL" - cpfs = [row[0] for row in db.execute_query(query)] - total_cpfs = len(cpfs) - logging.info(f"Total de CPFs encontrados: {total_cpfs}") - - for idx, cpf in enumerate(cpfs, 1): - try: - logging.info(f"Consultando CPF {cpf} [{idx}/{total_cpfs}]") - - context = { - "siglaSistema": "PETRVS-IPEA", - "nomeSistema": "PDG-PETRVS-IPEA", - "senha": os.getenv("SIAPE_PASSWORD_USER"), - "cpf": cpf, - "codOrgao": "45206", - "parmExistPag": "b", - "parmTipoVinculo": "c", - } - - resposta_xml = cliente_siape.call("consultaDadosPessoais.xml.j2", context) - logging.debug(f"XML bruto para CPF {cpf}:\n{resposta_xml}") - - dados = ClienteSiape.parse_xml_to_dict(resposta_xml) - logging.debug(f"Dados parseados para CPF {cpf}: {dados}") - - if not dados: - logging.warning( - f"Nenhum dado encontrado para CPF {cpf} [{idx}/{total_cpfs}]" - ) - continue - - dados["cpf"] = cpf - dados["dt_ingest"] = datetime.now().isoformat() - logging.info(f"Dados finais prontos para inserção: {dados}") - - db.alter_table( - data=dados, - table_name="dados_pessoais", - schema="siape", - ) - - db.insert_data( - [dados], - table_name="dados_pessoais", - conflict_fields=["cpf"], - primary_key=["cpf"], - schema="siape", - ) - - logging.info( - f"Dado inserido com sucesso para CPF {cpf} [{idx}/{total_cpfs}]" - ) - - except Exception as e: - logging.error( - f"Erro ao processar CPF {cpf} [{idx}/{total_cpfs}]: {e}", - exc_info=True, - ) - continue - - fetch_and_store_dados_pessoais() - - -dag_instance = siape_dados_pessoais_dag() diff --git a/dags/data_ingest/siape/dados_uorg_siape_ingest_dag.py b/dags/data_ingest/siape/dados_uorg_siape_ingest_dag.py deleted file mode 100644 index 1220ab79..00000000 --- a/dags/data_ingest/siape/dados_uorg_siape_ingest_dag.py +++ /dev/null @@ -1,84 +0,0 @@ -import os -import logging -from datetime import datetime, timedelta -from airflow.decorators import dag, task -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_siape import ClienteSiape -from cliente_postgres import ClientPostgresDB - - -@dag( - schedule_interval=get_dynamic_schedule("dados_uorg_siape_ingest_dag"), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "owner": "Joyce", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["siape", "dados_uorg"], -) -def siape_dados_uorg_dag() -> None: - """ - DAG que consome o endpoint consultaDadosUorg da API SIAPE - e armazena os dados da unidade organizacional do servidor no schema 'siape'. - """ - - @task - def fetch_and_store_dados_uorg() -> None: - logging.info("Iniciando extração de dados de UORG por CPF") - cliente_siape = ClienteSiape() - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - - query = "SELECT DISTINCT cpf FROM siape.lista_servidores WHERE cpf IS NOT NULL" - cpfs = [row[0] for row in db.execute_query(query)] - logging.info(f"Total de CPFs encontrados: {len(cpfs)}") - - for cpf in cpfs: - try: - context = { - "siglaSistema": "PETRVS-IPEA", - "nomeSistema": "PDG-PETRVS-IPEA", - "senha": os.getenv("SIAPE_PASSWORD_USER"), - "cpf": cpf, - "codOrgao": "45206", - "parmExistPag": "b", - "parmTipoVinculo": "c", - } - - resposta_xml = cliente_siape.call("consultaDadosUorg.xml.j2", context) - dados = ClienteSiape.parse_xml_to_dict(resposta_xml) - - if not dados: - logging.warning(f"Nenhum dado de UORG encontrado para CPF {cpf}") - continue - - dados["cpf"] = cpf - dados["dt_ingest"] = datetime.now().isoformat() - - db.alter_table( - data=dados, - table_name="dados_uorg", - schema="siape", - ) - - db.insert_data( - [dados], - table_name="dados_uorg", - conflict_fields=["cpf"], - primary_key=["cpf"], - schema="siape", - ) - - logging.info(f"Dado de UORG inserido para CPF {cpf}") - - except Exception as e: - logging.error(f"Erro ao processar CPF {cpf}: {e}") - continue - - fetch_and_store_dados_uorg() - - -dag_instance = siape_dados_uorg_dag() diff --git a/dags/data_ingest/siape/lista_aposentadoria_siape_ingest_dag.py b/dags/data_ingest/siape/lista_aposentadoria_siape_ingest_dag.py deleted file mode 100644 index 4afbb3be..00000000 --- a/dags/data_ingest/siape/lista_aposentadoria_siape_ingest_dag.py +++ /dev/null @@ -1,90 +0,0 @@ -import os -import time -import logging -from datetime import datetime, timedelta -from airflow.decorators import dag, task -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_siape import ClienteSiape -from cliente_postgres import ClientPostgresDB - - -@dag( - schedule_interval=get_dynamic_schedule("lista_aposentadoria_siape_ingest_dag"), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "owner": "Joyce", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["siape", "aposentadoria"], -) -def siape_lista_info_aposentadoria_dag() -> None: - """ - DAG que consome o endpoint listaInformacoesAposentadoria da API SIAPE - e armazena os dados no schema 'siape'. - """ - - @task - def fetch_and_store_aposentadoria_info() -> None: - logging.info("Iniciando extração de informações de aposentadoria por CPF") - cliente_siape = ClienteSiape() - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - - query = """ - SELECT DISTINCT cpf, matriculasiape - FROM siape.dados_funcionais - WHERE cpf IS NOT NULL AND matriculasiape IS NOT NULL - """ - registros = db.execute_query(query) - logging.info(f"Total de registros encontrados: {len(registros)}") - - for cpf, matricula in registros: - try: - context = { - "siglaSistema": "PETRVS-IPEA", - "nomeSistema": "PDG-PETRVS-IPEA", - "senha": os.getenv("SIAPE_PASSWORD_USER"), - "cpf": cpf, - "orgao": "45206", - "matricula": matricula, - } - - resposta_xml = cliente_siape.call( - "listaInformacoesAposentadoria.xml.j2", context - ) - dados = ClienteSiape.parse_xml_to_dict(resposta_xml) - - if not dados: - logging.warning(f"Nenhum dado encontrado para CPF {cpf}") - continue - - dados["dt_ingest"] = datetime.now().isoformat() - - db.alter_table( - data=dados, - table_name="info_aposentadoria", - schema="siape", - ) - db.insert_data( - [dados], - table_name="info_aposentadoria", - conflict_fields=["cpf"], - primary_key=["cpf"], - schema="siape", - ) - - logging.info(f"Dado de aposentadoria inserido para CPF {cpf}") - - except Exception as e: - logging.error(f"Erro ao processar CPF {cpf}: {e}") - continue - - time.sleep(0.1) - - fetch_and_store_aposentadoria_info() - - -dag_instance = siape_lista_info_aposentadoria_dag() diff --git a/dags/data_ingest/siape/lista_servidores_siape_ingest_dag.py b/dags/data_ingest/siape/lista_servidores_siape_ingest_dag.py deleted file mode 100644 index 69eb340f..00000000 --- a/dags/data_ingest/siape/lista_servidores_siape_ingest_dag.py +++ /dev/null @@ -1,82 +0,0 @@ -import os -import logging -from datetime import datetime, timedelta -from airflow.decorators import dag, task -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_siape import ClienteSiape -from cliente_postgres import ClientPostgresDB - - -@dag( - schedule_interval=get_dynamic_schedule("lista_servidores_siape_ingest_dag"), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "owner": "Joyce", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["siape", "lista_servidores"], -) -def siape_lista_servidores_dag() -> None: - - @task - def fetch_and_store_lista_servidores() -> None: - logging.info("Iniciando extração de servidores por UORG") - cliente_siape = ClienteSiape() - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - - query = "SELECT codigo FROM siape.lista_uorgs" - codigos_uorg = [row[0] for row in db.execute_query(query)] - logging.info(f"Total de UORGs encontradas: {len(codigos_uorg)}") - - ns = { - "soapenv": "http://schemas.xmlsoap.org/soap/envelope/", - "ns1": "http://servico.wssiapenet", - "ns2": "http://entidade.wssiapenet", - } - - for cod in codigos_uorg: - try: - context = { - "siglaSistema": "PETRVS-IPEA", - "nomeSistema": "PDG-PETRVS-IPEA", - "senha": os.getenv("SIAPE_PASSWORD_USER"), - "cpf": os.getenv("SIAPE_CPF_USER"), - "codOrgao": "45206", - "codUorg": cod, - } - - resposta_xml = cliente_siape.call("listaServidores.xml.j2", context) - dados = ClienteSiape.parse_xml_to_list( - xml_string=resposta_xml, element_tag="ns2:Servidor", namespaces=ns - ) - - if not dados: - logging.info(f"Nenhum servidor encontrado para UORG {cod}") - continue - - for row in dados: - row["codUorg"] = str(cod) - row["dt_ingest"] = datetime.now().isoformat() - - db.insert_data( - dados, - table_name="lista_servidores", - conflict_fields=["cpf", "codUorg"], - primary_key=["cpf", "codUorg"], - schema="siape", - ) - - logging.info(f"{len(dados)} servidores inseridos para UORG {cod}") - - except Exception as e: - logging.error(f"Erro ao processar UORG {cod}: {e}") - continue - - fetch_and_store_lista_servidores() - - -dag_instance = siape_lista_servidores_dag() diff --git a/dags/data_ingest/siape/lista_uorgs_siape_ingest_dag.py b/dags/data_ingest/siape/lista_uorgs_siape_ingest_dag.py deleted file mode 100644 index 539aa34b..00000000 --- a/dags/data_ingest/siape/lista_uorgs_siape_ingest_dag.py +++ /dev/null @@ -1,113 +0,0 @@ -import os -import logging -from datetime import datetime -from airflow.decorators import dag, task -from datetime import timedelta -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_siape import ClienteSiape -from cliente_postgres import ClientPostgresDB - - -@dag( - schedule_interval=get_dynamic_schedule("lista_uorgs_siape_ingest_dag"), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "owner": "Joyce", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["siape", "lista_uorgs"], -) -def siape_lista_uorgs_dag() -> None: - """ - DAG que extrai a lista de UORGs do SIAPE via API SOAP - e insere no schema 'siape', tabela 'lista_uorgs'. - """ - - @task - def fetch_and_store_lista_uorgs() -> None: - logging.info("[siape_lista_uorgs_dag] Iniciando extração da lista de UORGs") - - cliente_siape = ClienteSiape() - - context = { - "siglaSistema": "PETRVS-IPEA", - "nomeSistema": "PDG-PETRVS-IPEA", - "senha": os.getenv("SIAPE_PASSWORD_USER"), - "cpf": os.getenv("SIAPE_CPF_USER"), - "codOrgao": "45206", - } - - resposta_xml = cliente_siape.call("listaUorgs.xml.j2", context) - - ns = { - "soapenv": "http://schemas.xmlsoap.org/soap/envelope/", - "ns1": "http://servico.wssiapenet", - "ns2": "http://entidade.wssiapenet", - } - - dados_lista = ClienteSiape.parse_xml_to_list( - xml_string=resposta_xml, element_tag="ns2:Uorg", namespaces=ns - ) - - if not dados_lista: - logging.warning("Nenhum dado retornado da API listaUorgs") - return - - # Adicionar dt_ingest a cada registro - for registro in dados_lista: - registro["dt_ingest"] = datetime.now().isoformat() - - for item in dados_lista: - if "dataUltimaTransacao" in item: - valor_bruto = item.pop("dataUltimaTransacao") - try: - if valor_bruto and valor_bruto.isdigit() and len(valor_bruto) == 8: - item["dt_ultima_transacao"] = ( - datetime.strptime(valor_bruto, "%d%m%Y").date().isoformat() - ) - else: - item["dt_ultima_transacao"] = None - except Exception as e: - logging.warning(f"Erro ao converter data: {valor_bruto} - {e}") - item["dt_ultima_transacao"] = None - - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - - logging.info("Inserindo dados no banco de dados") - - ddl = """ - DO $$ - BEGIN - IF NOT EXISTS ( - SELECT 1 FROM information_schema.table_constraints - WHERE table_schema = 'siape' - AND table_name = 'lista_uorgs' - AND constraint_type = 'PRIMARY KEY' - ) THEN - ALTER TABLE siape.lista_uorgs - ADD CONSTRAINT lista_uorgs_pkey - PRIMARY KEY (codigo); - END IF; - END - $$; - """ - db.execute_non_query(ddl) - - db.insert_data( - dados_lista, - table_name="lista_uorgs", - conflict_fields=["codigo"], - primary_key=["codigo"], - schema="siape", - ) - - logging.info("Dados inseridos com sucesso") - - fetch_and_store_lista_uorgs() - - -dag_instance = siape_lista_uorgs_dag() diff --git a/dags/data_ingest/siape/pensoes_instituidas_siape_ingest_dag.py b/dags/data_ingest/siape/pensoes_instituidas_siape_ingest_dag.py deleted file mode 100644 index 0caa044e..00000000 --- a/dags/data_ingest/siape/pensoes_instituidas_siape_ingest_dag.py +++ /dev/null @@ -1,108 +0,0 @@ -import os -import logging -import requests -from datetime import datetime, timedelta -from airflow.decorators import dag, task -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_siape import ClienteSiape -from cliente_postgres import ClientPostgresDB - - -@dag( - schedule_interval=get_dynamic_schedule("pensoes_instituidas_siape_ingest_dag"), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "owner": "Davi", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["siape", "pensoes_instituidas"], -) -def siape_pensoes_instituidas_dag() -> None: - """ - DAG que consome o endpoint consultaPensoesInstituidas da API SIAPE - e armazena dados de pensões instituídas no schema 'siape'. - """ - - @task - def fetch_and_store_pensoes_instituidas() -> None: - logging.info("Iniciando extração de dados de pensões instituídas por CPF") - cliente_siape = ClienteSiape() - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - - query = "SELECT DISTINCT cpf FROM siape.lista_servidores WHERE cpf IS NOT NULL" - cpfs = [row[0] for row in db.execute_query(query)] - logging.info(f"Total de CPFs encontrados: {len(cpfs)}") - - for cpf in cpfs: - try: - context = { - "siglaSistema": "PETRVS-IPEA", - "nomeSistema": "PDG-PETRVS-IPEA", - "senha": os.getenv("SIAPE_PASSWORD_USER"), - "cpf": cpf, - "codOrgao": "45206", - "parmExistPag": "b", - "parmTipoVinculo": "c", - } - - resposta_xml = cliente_siape.call( - "consultaPensoesInstituidas.xml.j2", context - ) - dados = ClienteSiape.parse_pensoes_instituidas(resposta_xml) - - if not dados: - logging.warning(f"Nenhum dado de pensão instituída para CPF {cpf}") - continue - - # Adiciona CPF a cada registro e gera ID único - for i, registro in enumerate(dados): - registro["cpf"] = cpf - # Cria ID único baseado em CPF + índice + campos únicos - base_id = f"{cpf}_{i}" - cpf_pensionista = registro.get("cpfPensionista", "") - matricula_pensionista = registro.get("matriculaPensionista", "") - identificador = f"{base_id}_{cpf_pensionista}_{matricula_pensionista}" - registro["id_registro"] = identificador - - if dados: - # Adicionar dt_ingest a cada registro - for registro in dados: - registro["dt_ingest"] = datetime.now().isoformat() - - # Usa o primeiro registro para criar/ajustar a estrutura da tabela - db.alter_table( - data=dados[0], - table_name="pensoes_instituidas", - schema="siape", - ) - - db.insert_data( - dados, - table_name="pensoes_instituidas", - conflict_fields=["id_registro"], - primary_key=["id_registro"], - schema="siape", - ) - - logging.info( - f"Inseridos {len(dados)} registros de pensões para CPF {cpf}" - ) - - except requests.exceptions.HTTPError as e: - if "500" in str(e): - logging.warning(f"Servidor retornou erro 500 para CPF {cpf}") - else: - logging.error(f"Erro HTTP ao processar CPF {cpf}: {e}") - continue - except Exception as e: - logging.error(f"Erro ao processar CPF {cpf}: {e}") - continue - - fetch_and_store_pensoes_instituidas() - - -dag_instance = siape_pensoes_instituidas_dag() diff --git a/dags/data_ingest/siorg/cargos_funcao_ingest_dag.py b/dags/data_ingest/siorg/cargos_funcao_ingest_dag.py deleted file mode 100644 index b065b2f5..00000000 --- a/dags/data_ingest/siorg/cargos_funcao_ingest_dag.py +++ /dev/null @@ -1,58 +0,0 @@ -import logging -from airflow.decorators import dag, task -from datetime import datetime, timedelta -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_siorg import ClienteSiorg -from cliente_postgres import ClientPostgresDB - - -@dag( - schedule_interval=get_dynamic_schedule( - "dados_afastamento_historico_siape_ingest_dag" - ), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "retries": 1, - "retry_delay": timedelta(minutes=5), - "owner": "Davi", - }, - tags=["estrutura_organizacional", "siorg"], -) -def api_cargos_funcao_dag() -> None: - @task - def fetch_and_store_cargos_funcao() -> None: - api = ClienteSiorg() - db = ClientPostgresDB(get_postgres_conn()) - try: - cargos_funcao_data = api.get_cargos_funcao() - if not cargos_funcao_data: - logging.warning("Nenhum dado retornado pela API de cargos/função.") - return - - registros = [] - for tipo in cargos_funcao_data: - tipo_base = {k: v for k, v in tipo.items() if k != "cargosFuncoes"} - if "cargosFuncoes" in tipo and "cargoFuncao" in tipo["cargosFuncoes"]: - for cargo in tipo["cargosFuncoes"]["cargoFuncao"]: - registro = {**tipo_base, **cargo} - registro["dt_ingest"] = datetime.now().isoformat() - registros.append(registro) - if registros: - db.insert_data( - registros, - "cargos_funcao", - conflict_fields=["codigoCargoFuncao"], - primary_key=["codigoCargoFuncao"], - schema="siorg", - ) - else: - logging.warning("Nenhum cargo/função encontrado para inserir.") - except Exception as e: - logging.error(f"Erro ao buscar/inserir cargos função: {e}") - - fetch_and_store_cargos_funcao() - - -dag_instance = api_cargos_funcao_dag() diff --git a/dags/data_ingest/siorg/estrutura_organizacional_cargos_ingest_dag.py b/dags/data_ingest/siorg/estrutura_organizacional_cargos_ingest_dag.py deleted file mode 100644 index 861f1d71..00000000 --- a/dags/data_ingest/siorg/estrutura_organizacional_cargos_ingest_dag.py +++ /dev/null @@ -1,67 +0,0 @@ -import logging -from airflow.decorators import dag, task -from datetime import datetime, timedelta -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_siorg import ClienteSiorg -from cliente_postgres import ClientPostgresDB - - -@dag( - schedule_interval=get_dynamic_schedule("estrutura_organizacional_cargos_ingest_dag"), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={"retries": 1, "retry_delay": timedelta(minutes=5), "owner": "Davi"}, - tags=["estrutura_organizacional", "siorg"], -) -def api_estrutura_organizacional_cargos_dag() -> None: - """Busca dados da estrutura organizacional via API e armazena no PostgreSQL.""" - - @task - def fetch_estrutura_organizacional_cargos() -> None: - try: - api = ClienteSiorg() - db = ClientPostgresDB(get_postgres_conn()) - codigo_unidades = db.get_codigo_unidade() - - if not codigo_unidades: - logging.warning("Nenhum código de unidade encontrado.") - return - - for unidade in codigo_unidades: - codigo_unidade = unidade["codigounidade"] - ordem_grandeza = unidade["ordem_grandeza"] - - try: - estrutura_cargos = api.get_estrutura_organizacional_cargos( - codigo_unidade - ) - - if estrutura_cargos: - estrutura_cargos["ordem_grandeza"] = ordem_grandeza - estrutura_cargos["dt_ingest"] = datetime.now().isoformat() - - db.insert_data( - [estrutura_cargos], - "estrutura_organizacional_cargos", - conflict_fields=["codigoUnidade"], - primary_key=["codigoUnidade"], - schema="siorg", - ) - else: - logging.debug(f"Sem dados para codigoUnidade {codigo_unidade}.") - - except Exception as e: - logging.error( - f"Erro ao processar codigoUnidade {codigo_unidade}: {e}", - exc_info=True, - ) - - except Exception as e: - logging.error(f"Erro geral na tarefa: {e}", exc_info=True) - raise - - fetch_estrutura_organizacional_cargos() - - -dag_instance = api_estrutura_organizacional_cargos_dag() diff --git a/dags/data_ingest/siorg/unidade_organizacional_ingest_dag.py b/dags/data_ingest/siorg/unidade_organizacional_ingest_dag.py deleted file mode 100755 index e88ea27b..00000000 --- a/dags/data_ingest/siorg/unidade_organizacional_ingest_dag.py +++ /dev/null @@ -1,82 +0,0 @@ -import logging -from airflow.decorators import dag, task -from datetime import datetime, timedelta -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_siorg import ClienteSiorg -from cliente_postgres import ClientPostgresDB - - -@dag( - schedule_interval=get_dynamic_schedule("unidade_organizacional_ingest_dag"), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["estrutura_organizacional", "siorg"], -) -def api_unidade_organizacional_dag() -> None: - """DAG para buscar e armazenar dados da Estrutura Organizacional - de uma API no PostgreSQL.""" - - @task - def fetch_estrutura_organizacional_resumida() -> None: - logging.info( - "[unidade_organizacional_ingest_dag.py] " - "Starting fetch_estrutura_organizacional_resumida task" - ) - api = ClienteSiorg() - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - - codigo_poder = "1" - codigo_esfera = "1" - codigo_unidade = "7" - - try: - logging.info( - "[unidade_organizacional_ingest_dag.py] " - "Fetching estrutura organizacional resumida for " - f"codigoUnidade: {codigo_unidade}" - ) - estrutura_resumida = api.get_estrutura_organizacional_resumida( - codigo_poder=codigo_poder, - codigo_esfera=codigo_esfera, - codigo_unidade=codigo_unidade, - ) - if estrutura_resumida: - # Adicionar dt_ingest a cada item - for item in estrutura_resumida: - item["dt_ingest"] = datetime.now().isoformat() - - logging.info( - "[unidade_organizacional_ingest_dag.py] " - "Inserting estrutura organizacional resumida for " - f"codigoUnidade: {codigo_unidade} into PostgreSQL" - ) - db.insert_data( - estrutura_resumida, - "unidade_organizacional", - conflict_fields=["codigoUnidade"], - primary_key=["codigoUnidade"], - schema="siorg", - ) - else: - logging.warning( - "[unidade_organizacional_ingest_dag.py] " - "No estrutura organizacional resumida found for " - f"codigoUnidade: {codigo_unidade}" - ) - except Exception as e: - logging.error( - "[unidade_organizacional_ingest_dag.py] " - "Error fetching estrutura organizacional resumida for " - f"codigoUnidade {codigo_unidade}: {e}" - ) - - fetch_estrutura_organizacional_resumida() - - -dag_instance = api_unidade_organizacional_dag() diff --git a/dags/data_ingest/tesouro_gerencial/empenhos_tesouro_emendas_ingest_dag.py b/dags/data_ingest/tesouro_gerencial/empenhos_tesouro_emendas_ingest_dag.py deleted file mode 100644 index 868b4851..00000000 --- a/dags/data_ingest/tesouro_gerencial/empenhos_tesouro_emendas_ingest_dag.py +++ /dev/null @@ -1,197 +0,0 @@ -from typing import Dict, Any, Optional -from airflow import DAG -from airflow.operators.python import PythonOperator -from airflow.models import Variable -from airflow.models.param import Param -from datetime import datetime, timedelta -import logging -import json -from schedule_loader import get_dynamic_schedule -from cliente_email import fetch_and_process_email -from cliente_postgres import ClientPostgresDB -from postgres_helpers import get_postgres_conn -import pandas as pd -import io - -# Configurações básicas da DAG -default_args = { - "owner": "Tiago", - "depends_on_past": False, - "retries": 1, - "retry_delay": timedelta(minutes=5), -} - -COLUMN_MAPPING = { - 0: "emissao_mes", - 1: "emissao_dia", - 2: "programa_governo", - 3: "programa_governo_descricao", - 4: "acao_governo", - 5: "acao_governo_descricao", - 6: "autor_emendas_orcamento", - 7: "autor_emendas_orcamento_descricao", - 8: "uf_pt", - 9: "uf_pt_descricao", - 10: "municipio_pt", - 11: "ne_ccor", - 12: "ne_num_processo", - 13: "ne_info_complementar", - 14: "ne_ccor_descricao", - 15: "doc_observacao", - 16: "grupo_despesa", - 17: "grupo_despesa_descricao", - 18: "natureza_despesa", - 19: "natureza_despesa_descricao", - 20: "modalidade_aplicacao", - 21: "modalidade_aplicacao_descricao", - 22: "ne_ccor_favorecido", - 23: "ne_ccor_favorecido_descricao", - 24: "ne_ccor_ano_emissao", - 25: "ptres", - 26: "item_informacao", - 27: "item_informacao_descricao", - 28: "despesas_empenhadas", - 29: "despesas_liquidadas", - 30: "despesas_pagas", - 31: "restos_a_pagar_inscritos", - 32: "restos_a_pagar_pagos", -} - -EMAIL_SUBJECT = "notas_de_empenhos_emendas_parlamentares" -SKIPROWS = 12 - -# Configurações da DAG -with DAG( - dag_id="email_tesouro_emendas_ingest", - default_args=default_args, - description="Processa anexos dos empenhos vindo do email, formata e insere no db", - schedule_interval=get_dynamic_schedule("empenhos_tesouro_emendas_ingest_dag"), - start_date=datetime(2023, 12, 1), - catchup=False, - params={ - "data_referencia": Param( - default=None, - type=["string", "null"], - title="Data de Referencia", - description=( - "Data para filtrar os e-mails recebidos (formato YYYY-MM-DD). " - "Se nao informado, usa o dia atual." - ), - ) - }, - tags=["MIR", "email", "empenhos", "tesouro", "emendas"], -) as dag: - - def process_email_data(**context: Dict[str, Any]) -> Optional[Any]: - creds = json.loads(Variable.get("email_credentials")) - - EMAIL = creds["email"] - PASSWORD = creds["password"] - IMAP_SERVER = creds["imap_server"] - SENDER_EMAIL = creds["sender_email"] - params = context.get("params", {}) - data_referencia = params.get("data_referencia") - - target_date = None - if data_referencia: - try: - target_date = datetime.strptime(data_referencia, "%Y-%m-%d").date() - except ValueError as exc: - raise ValueError( - "Parametro 'data_referencia' invalido. Use o formato YYYY-MM-DD." - ) from exc - - try: - logging.info( - "Iniciando o processamento dos emails para a data: %s", - target_date.isoformat() if target_date else "dia atual", - ) - csv_data = fetch_and_process_email( - IMAP_SERVER, - EMAIL, - PASSWORD, - SENDER_EMAIL, - EMAIL_SUBJECT, - COLUMN_MAPPING, - skiprows=SKIPROWS, - target_date=target_date, - ) - if not csv_data: - logging.warning( - "Nenhum CSV valido foi extraido dos e-mails encontrados " - "para o assunto esperado." - ) - return None - - logging.info( - "CSV processado com sucesso. Dados encontrados: %s", len(csv_data) - ) - return csv_data - except Exception as e: - logging.error("Erro no processamento dos emails: %s", str(e)) - raise - - def insert_data_to_db(**context: Dict[str, Any]) -> None: - """ - Função para inserir os dados no banco de dados. - Os dados do CSV são recuperados do XCom. - """ - try: - task_instance: Any = context["ti"] - csv_data: Any = task_instance.xcom_pull(task_ids="process_emails") - - if not csv_data: - logging.warning("Nenhum dado para inserir no banco.") - return - - df = pd.read_csv(io.StringIO(csv_data)) - df = df[df["ne_ccor_ano_emissao"].astype(str).str.startswith("20")] - data = df.to_dict(orient="records") - - # Adicionar dt_ingest a cada registro - for record in data: - record["dt_ingest"] = datetime.now().isoformat() - - postgres_conn_str = get_postgres_conn("postgres_mir") - db = ClientPostgresDB(postgres_conn_str) - - unique_key = [ - "ne_ccor", - "natureza_despesa", - "doc_observacao", - "ne_ccor_ano_emissao", - "emissao_dia", - "emissao_mes", - "despesas_empenhadas", - "despesas_liquidadas", - "despesas_pagas", - ] - - db.insert_data( - data, - "empenhos_tesouro_emendas_parlamentares", - conflict_fields=unique_key, - primary_key=unique_key, - schema="siafi", - ) - logging.info("Dados inseridos com sucesso no banco de dados.") - except Exception as e: - logging.error("Erro ao inserir dados no banco: %s", str(e)) - raise - - # Tarefa 1: Processar os e-mails e retornar CSV - process_emails_task = PythonOperator( - task_id="process_emails", - python_callable=process_email_data, - provide_context=True, - ) - - # Tarefa 2: Inserir os dados no banco de dados - insert_to_db_task = PythonOperator( - task_id="insert_to_db", - python_callable=insert_data_to_db, - provide_context=True, - ) - - # Fluxo da DAG - process_emails_task >> insert_to_db_task diff --git a/dags/data_ingest/tesouro_gerencial/empenhos_tesouro_ingest_dag.py b/dags/data_ingest/tesouro_gerencial/empenhos_tesouro_ingest_dag.py deleted file mode 100755 index fc91e8a4..00000000 --- a/dags/data_ingest/tesouro_gerencial/empenhos_tesouro_ingest_dag.py +++ /dev/null @@ -1,154 +0,0 @@ -from typing import Dict, Any, Optional -from airflow import DAG -from airflow.operators.python import PythonOperator -from airflow.models import Variable -from datetime import datetime, timedelta -import logging -import json -from schedule_loader import get_dynamic_schedule -from cliente_email import fetch_and_process_email -from cliente_postgres import ClientPostgresDB -from postgres_helpers import get_postgres_conn -import pandas as pd -import io - -# Configurações básicas da DAG -default_args = { - "owner": "Davi", - "depends_on_past": False, - "retries": 1, - "retry_delay": timedelta(minutes=5), -} - -COLUMN_MAPPING = { - 0: "emissao_mes", - 1: "emissao_dia", - 2: "ne_ccor", - 3: "ne_num_processo", - 4: "ne_info_complementar", - 5: "ne_ccor_descricao", - 6: "doc_observacao", - 7: "natureza_despesa", - 8: "natureza_despesa_descricao", - 9: "ne_ccor_favorecido", - 10: "ne_ccor_favorecido_descricao", - 11: "ne_ccor_ano_emissao", - 12: "ptres", - 13: "fonte_recursos_detalhada", - 14: "fonte_recursos_detalhada_descricao", - 15: "despesas_empenhadas", - 16: "despesas_liquidadas", - 17: "despesas_pagas", - 18: "restos_a_pagar_inscritos", - 19: "restos_a_pagar_pagos", -} - -EMAIL_SUBJECT = "notas_de_empenhos_a_partir_de_2024" -SKIPROWS = 9 - -# Configurações da DAG -with DAG( - dag_id="email_empenhos_tesouro_ingest", - default_args=default_args, - description="Processa anexos dos empenhos vindo do email, formata e insere no db", - schedule_interval=get_dynamic_schedule("empenhos_tesouro_ingest_dag"), - start_date=datetime(2023, 12, 1), - catchup=False, - tags=["email", "empenhos", "tesouro"], -) as dag: - - def process_email_data(**context: Dict[str, Any]) -> Optional[Any]: - creds = json.loads(Variable.get("email_credentials")) - - EMAIL = creds["email"] - PASSWORD = creds["password"] - IMAP_SERVER = creds["imap_server"] - SENDER_EMAIL = creds["sender_email"] - - try: - logging.info("Iniciando o processamento dos emails...") - csv_data = fetch_and_process_email( - IMAP_SERVER, - EMAIL, - PASSWORD, - SENDER_EMAIL, - EMAIL_SUBJECT, - COLUMN_MAPPING, - skiprows=SKIPROWS, - ) - if not csv_data: - logging.warning("Nenhum e-mail encontrado com o assunto esperado.") - return None - - logging.info( - "CSV processado com sucesso. Dados encontrados: %s", len(csv_data) - ) - return csv_data - except Exception as e: - logging.error("Erro no processamento dos emails: %s", str(e)) - raise - - def insert_data_to_db(**context: Dict[str, Any]) -> None: - """ - Função para inserir os dados no banco de dados. - Os dados do CSV são recuperados do XCom. - """ - try: - task_instance: Any = context["ti"] - csv_data: Any = task_instance.xcom_pull(task_ids="process_emails") - - if not csv_data: - logging.warning("Nenhum dado para inserir no banco.") - return - - df = pd.read_csv(io.StringIO(csv_data)) - df = df[df["ne_ccor_ano_emissao"].astype(str).str.startswith("20")] - data = df.to_dict(orient="records") - - # Adicionar dt_ingest a cada registro - for record in data: - record["dt_ingest"] = datetime.now().isoformat() - - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - - unique_key = [ - "ne_ccor", - "natureza_despesa", - "doc_observacao", - "ne_ccor_ano_emissao", - "emissao_dia", - "emissao_mes", - "despesas_empenhadas", - "despesas_liquidadas", - "despesas_pagas", - ] - - db.insert_data( - data, - "empenhos_tesouro", - conflict_fields=unique_key, - primary_key=unique_key, - schema="siafi", - ) - logging.info("Dados inseridos com sucesso no banco de dados.") - except Exception as e: - logging.error("Erro ao inserir dados no banco: %s", str(e)) - raise - - # Tarefa 1: Processar os e-mails e retornar CSV - process_emails_task = PythonOperator( - task_id="process_emails", - python_callable=process_email_data, - provide_context=True, - ) - - # Tarefa 2: Inserir os dados no banco de dados - insert_to_db_task = PythonOperator( - task_id="insert_to_db", - python_callable=insert_data_to_db, - provide_context=True, - ) - - # Fluxo da DAG - process_emails_task >> insert_to_db_task diff --git a/dags/data_ingest/tesouro_gerencial/mcid/dotacao_execucao_outras_fontes_mcid_ingest_dag.py b/dags/data_ingest/tesouro_gerencial/mcid/dotacao_execucao_outras_fontes_mcid_ingest_dag.py deleted file mode 100644 index 85525dae..00000000 --- a/dags/data_ingest/tesouro_gerencial/mcid/dotacao_execucao_outras_fontes_mcid_ingest_dag.py +++ /dev/null @@ -1,183 +0,0 @@ -import io -import json -import logging -from datetime import datetime, timedelta -from typing import Any, Dict, List, Optional - -import cliente_email -import pandas as pd -from airflow import DAG -from airflow.exceptions import AirflowSkipException -from airflow.models import Variable -from airflow.operators.python import PythonOperator -from cliente_email import fetch_and_process_email -from cliente_postgres import ClientPostgresDB -from postgres_helpers import get_postgres_conn -from schedule_loader import get_dynamic_schedule - -default_args = { - "owner": "Lucas", - "depends_on_past": False, - "retries": 1, - "retry_delay": timedelta(minutes=5), -} - -COLUMN_MAPPING = { - 0: "unidade_orcamentaria_codigo", - 1: "unidade_orcamentaria_nome", - 2: "acao_governo_codigo", - 3: "acao_governo_nome", - 4: "programa_governo_codigo", - 5: "programa_governo_nome", - 6: "plano_orcamentario_codigo", - 7: "plano_orcamentario_funcao", - 8: "plano_orcamentario_subfuncao", - 9: "plano_orcamentario_programa", - 10: "plano_orcamentario_acao", - 11: "plano_orcamentario_medida", - 12: "plano_orcamentario_descricao", - 13: "elemento_despesa_codigo", - 14: "elemento_despesa_nome", - 15: "orgao_uge_codigo", - 16: "orgao_uge_nome", - 17: "uge_matriz_filial", - 18: "ug_executora_codigo", - 19: "ug_executora_nome", - 20: "fixacao_despesa_loa", - 21: "dotacao_inicial", - 22: "dotacao_atualizada", - 23: "credito_disponivel", - 24: "despesas_empenhadas", - 25: "despesas_empenhadas_a_liquidar", - 26: "despesas_liquidadas_a_pagar", - 27: "despesas_pagas", - 28: "restos_a_pagar_inscritos", - 29: "restos_a_pagar_pagos", -} - -EMAIL_SUBJECT = "dotacao_execucao_outras_fontes_mcid" -SKIPROWS = 12 - - -def _patched_format_csv( - csv_data: str, - column_mapping: Optional[Dict[int, str]], - skiprows: int, -) -> pd.DataFrame: - """Substitui o format_csv do cliente_email com suporte a UTF-16 e TSV.""" - # Decodifica UTF-16 se ainda vier como bytes - if isinstance(csv_data, bytes): - csv_data = csv_data.decode("utf-16") - - if column_mapping: - df = pd.read_csv( - io.StringIO(csv_data), - skiprows=skiprows, - header=None, - sep="\t", - engine="python", - on_bad_lines="skip", - ) - column_names: List[str] = [ - column_mapping.get(i, f"col_{i}") for i in range(len(df.columns)) - ] - df.columns = pd.Index(column_names) - else: - df = pd.read_csv( - io.StringIO(csv_data), - skiprows=skiprows, - header=0, - sep="\t", - engine="python", - on_bad_lines="skip", - ) - return df - - -with DAG( - dag_id="dotacao_execucao_outras_fontes_mcid_ingest_dag", - default_args=default_args, - description="Processa e ingere dados de execução de outras fontes de MCID", - schedule_interval=get_dynamic_schedule("dotacao_execucao_outras_fontes_mcid"), - catchup=False, - start_date=datetime(2026, 3, 27), - tags=["email", "mcid", "tesouro", "dotacao", "execucao"], -) as dag: - - def process_email_data(**context: Dict[str, Any]) -> Optional[Any]: - creds = json.loads(Variable.get("email_credentials")) - - EMAIL = creds["email"] - PASSWORD = creds["password"] - IMAP_SERVER = creds["imap_server"] - SENDER_EMAIL = creds["sender_email"] - - cliente_email.format_csv = _patched_format_csv - - try: - logging.info("Iniciando o processamento dos emails") - csv_data = fetch_and_process_email( - IMAP_SERVER, - EMAIL, - PASSWORD, - SENDER_EMAIL, - EMAIL_SUBJECT, - COLUMN_MAPPING, - skiprows=SKIPROWS, - ) - if not csv_data: - logging.warning("Nenhum e-mail encontrado com o assunto esperado.") - raise AirflowSkipException("Nenhum e-mail encontrado. Task ignorada.") - - logging.info( - "CSV processado com sucesso. Registros encontrados: %s", len(csv_data) - ) - return csv_data - except Exception as e: - logging.error("Erro no processamento dos emails: %s", str(e)) - raise - - def insert_data_to_db(**context: Dict[str, Any]) -> None: - try: - task_instance: Any = context["ti"] - csv_data: Any = task_instance.xcom_pull(task_ids="process_emails") - - if not csv_data: - logging.warning("Nenhum dado para inserir no banco.") - raise AirflowSkipException( - "Nenhum dado foi encontrado para inserção no BD" - ) - - df = pd.read_csv(io.StringIO(csv_data)) - data = df.to_dict(orient="records") - - for record in data: - record["dt_ingest"] = datetime.now().isoformat() - - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - - - db.insert_data( - data, - "dotacao_execucao_outras_fontes_mcid", - schema="siafi", - ) - logging.info("Dados inseridos com sucesso no banco de dados.") - except Exception as e: - logging.error("Erro ao inserir dados no banco: %s", str(e)) - raise - - process_emails_task = PythonOperator( - task_id="process_emails", - python_callable=process_email_data, - provide_context=True, - ) - - insert_to_db_task = PythonOperator( - task_id="insert_to_db", - python_callable=insert_data_to_db, - provide_context=True, - ) - - process_emails_task >> insert_to_db_task diff --git a/dags/data_ingest/tesouro_gerencial/mcid/empenho_emendas_parlamentares_ingest_dag.py b/dags/data_ingest/tesouro_gerencial/mcid/empenho_emendas_parlamentares_ingest_dag.py deleted file mode 100644 index 21524328..00000000 --- a/dags/data_ingest/tesouro_gerencial/mcid/empenho_emendas_parlamentares_ingest_dag.py +++ /dev/null @@ -1,155 +0,0 @@ -import io -import json -import logging -from datetime import datetime, timedelta -from typing import Any, Dict, Optional - -import pandas as pd -from airflow import DAG -from airflow.exceptions import AirflowSkipException -from airflow.models import Variable -from airflow.operators.python import PythonOperator -from cliente_email import fetch_and_process_email -from cliente_postgres import ClientPostgresDB -from postgres_helpers import get_postgres_conn -from schedule_loader import get_dynamic_schedule - -default_args = { - "owner": "Lucas", - "depends_on_past": False, - "retries": 1, - "retry_delay": timedelta(minutes=5), -} - -COLUMN_MAPPING = { - 0: "emissao_mes", - 1: "emissao_dia", - 2: "programa_governo_numero", - 3: "programa_governo_nome", - 4: "acao_governo_codigo", - 5: "acao_governo_nome", - 6: "autor_emendas_orcamento_codigo", - 7: "autor_emendas_orcamento_nome", - 8: "uf_codigo", - 9: "uf_nome", - 10: "municipio", - 11: "ne_ccor", - 12: "ne_num_processo", - 13: "ne_info_complementar", - 14: "ne_ccor_descricao", - 15: "doc_observacao", - 16: "grupo_despesa_codigo", - 17: "grupo_despesa_nome", - 18: "natureza_despesa_codigo", - 19: "natureza_despesa_nome", - 20: "modalidade_aplicacao_codigo", - 21: "modalidade_aplicacao_nome", - 22: "ne_ccor_favorecido_codigo", - 23: "ne_ccor_favorecido_nome", - 24: "ne_ccor_ano_emissao", - 25: "ptres", - 26: "fonte_recursos_detalhada", - 27: "fonte_recursos_detalhada_descricao", - 28: "restos_a_pagar_inscritos", - 29: "restos_a_pagar_pagos", -} - -EMAIL_SUBJECT = "notas_empenho_emendas_parlamentares_mcid" -SKIPROWS = 9 - -with DAG( - dag_id="empenho_emendas_parlamentares_ingest_dag", - default_args=default_args, - description="Processa e ingere dados de empenho de emendas parlamentares do MCID", - schedule_interval=get_dynamic_schedule("empenho_emendas_parlamentares_ingest_dag"), - start_date=datetime(2026, 3, 25), - catchup=False, - tags=["email", "empenhos", "tesouro", "emendas"], -) as dag: - - def process_email_data(**context: Dict[str, Any]) -> Optional[Any]: - creds = json.loads(Variable.get("email_credentials")) - - EMAIL = creds["email"] - PASSWORD = creds["password"] - IMAP_SERVER = creds["imap_server"] - SENDER_EMAIL = creds["sender_email"] - - try: - logging.info("Iniciando o processamento dos emails") - csv_data = fetch_and_process_email( - IMAP_SERVER, - EMAIL, - PASSWORD, - SENDER_EMAIL, - EMAIL_SUBJECT, - COLUMN_MAPPING, - skiprows=SKIPROWS, - ) - if not csv_data: - logging.warning("Nenhum e-mail encontrado com o assunto esperado.") - raise AirflowSkipException("Nenhum e-mail encontrado. Task ignorada.") - - logging.info( - "CSV processado com sucesso. Dados encontrados: %s", len(csv_data) - ) - return csv_data - except Exception as e: - logging.error("Erro no processamento dos emails: %s", str(e)) - raise - - def insert_data_to_db(**context: Dict[str, Any]) -> None: - try: - task_instance: Any = context["ti"] - csv_data: Any = task_instance.xcom_pull(task_ids="process_emails") - - if not csv_data: - logging.warning("Nenhum dado para inserir no banco.") - raise AirflowSkipException( - "Nenhum dado foi encontrado para inserção no BD" - ) - - df = pd.read_csv(io.StringIO(csv_data), skiprows=[1, 2, 3]) - df = df[df["ne_ccor_ano_emissao"].astype(str).str.startswith("20")] - data = df.to_dict(orient="records") - - for record in data: - record["dt_ingest"] = datetime.now().isoformat() - - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - - unique_key = [ - "ne_ccor", - "emissao_dia", - "emissao_mes", - "programa_governo_numero", - "programa_governo_nome", - "ne_num_processo", - ] - - db.insert_data( - data, - "empenho_emendas_parlamentares", - conflict_fields=unique_key, - primary_key=unique_key, - schema="siafi", - ) - logging.info("Dados inseridos com sucesso no banco de dados.") - except Exception as e: - logging.error("Erro ao inserir dados no banco: %s", str(e)) - raise - - process_emails_task = PythonOperator( - task_id="process_emails", - python_callable=process_email_data, - provide_context=True, - ) - - insert_to_db_task = PythonOperator( - task_id="insert_to_db", - python_callable=insert_data_to_db, - provide_context=True, - ) - - process_emails_task >> insert_to_db_task diff --git a/dags/data_ingest/tesouro_gerencial/mcid/orcamento_mcid_por_acao_ingest_dag.py b/dags/data_ingest/tesouro_gerencial/mcid/orcamento_mcid_por_acao_ingest_dag.py deleted file mode 100644 index 7df16e06..00000000 --- a/dags/data_ingest/tesouro_gerencial/mcid/orcamento_mcid_por_acao_ingest_dag.py +++ /dev/null @@ -1,194 +0,0 @@ -import io -import json -import logging -from datetime import datetime, timedelta -from typing import Any, Dict, List, Optional - -import cliente_email # importar o módulo, não só a função -import pandas as pd -from airflow import DAG -from airflow.exceptions import AirflowSkipException -from airflow.models import Variable -from airflow.operators.python import PythonOperator -from cliente_email import fetch_and_process_email -from cliente_postgres import ClientPostgresDB -from postgres_helpers import get_postgres_conn -from schedule_loader import get_dynamic_schedule - -default_args = { - "owner": "Lucas", - "depends_on_past": False, - "retries": 1, - "retry_delay": timedelta(minutes=5), -} - -COLUMN_MAPPING = { - 0: "acao_governo_codigo", - 1: "acao_governo_nome", - 2: "programa_governo_codigo", - 3: "programa_governo_nome", - 4: "ne_ccor", - 5: "ne_ccor_favorecido_codigo", - 6: "ne_ccor_favorecido_nome", - 7: "favorecido_cep", - 8: "favorecido_municipio_codigo", - 9: "favorecido_municipio_nome", - 10: "favorecido_regiao", - 11: "favorecido_ug_uf_codigo", - 12: "favorecido_ug_uf_nome", - 13: "fonte_recursos_detalhada", - 14: "fonte_recursos_detalhada_descricao", - 15: "pt", - 16: "ptres", - 17: "plano_orcamentario_ug_executora_codigo", - 18: "plano_orcamentario_cod1", - 19: "plano_orcamentario_cod2", - 20: "plano_orcamentario_programa", - 21: "plano_orcamentario_acao_orcamentaria", - 22: "plano_orcamentario_medida", - 23: "plano_orcamentario_descricao", - 24: "ug_executora_codigo", - 25: "ug_executora_nome", - 26: "ug_responsavel_codigo", - 27: "ug_responsavel_nome", - 28: "pl_codigo", - 29: "pl_nome", - 30: "natureza_despesa_codigo", - 31: "natureza_despesa_nome", - 32: "dotacao_inicial", - 33: "dotacao_atualizada", - 34: "despesas_empenhadas", - 35: "despesas_empenhadas_a_liquidar", - 36: "despesas_liquidadas_a_pagar", - 37: "despesas_pagas", -} - -EMAIL_SUBJECT = "orcamento_mcid_por_acao" -SKIPROWS = 10 - - -# A formatação do CSV estava como utf-16. -# Função criada para consumo sem erro de formatação -def _patched_format_csv( - csv_data: str, - column_mapping: Optional[Dict[int, str]], - skiprows: int, -) -> pd.DataFrame: - """Substitui o format_csv do cliente_email com suporte a UTF-16 e TSV.""" - # Decodifica UTF-16 se ainda vier como bytes - if isinstance(csv_data, bytes): - csv_data = csv_data.decode("utf-16") - - if column_mapping: - df = pd.read_csv( - io.StringIO(csv_data), - skiprows=skiprows, - header=None, - sep="\t", - engine="python", - on_bad_lines="skip", - ) - column_names: List[str] = [ - column_mapping.get(i, f"col_{i}") for i in range(len(df.columns)) - ] - df.columns = pd.Index(column_names) - else: - df = pd.read_csv( - io.StringIO(csv_data), - skiprows=skiprows, - header=0, - sep="\t", - engine="python", - on_bad_lines="skip", - ) - return df - - -with DAG( - dag_id="orcamento_mcid_por_acao_ingest_dag", - default_args=default_args, - description="Processa e ingere dados de orcamento por acao do MCID do Tesouro", - schedule_interval=get_dynamic_schedule("orcamento_mcid_por_acao_ingest_dag"), - start_date=datetime(2026, 3, 23), - catchup=False, - tags=["email", "orcamento", "tesouro", "mcid"], -) as dag: - - def process_email_data(**context: Dict[str, Any]) -> Optional[Any]: - creds = json.loads(Variable.get("email_credentials")) - - EMAIL = creds["email"] - PASSWORD = creds["password"] - IMAP_SERVER = creds["imap_server"] - SENDER_EMAIL = creds["sender_email"] - - # Monkey-patch: substitui format_csv do cliente_email pela versão corrigida - cliente_email.format_csv = _patched_format_csv - - try: - logging.info("Iniciando o processamento dos emails") - csv_data = fetch_and_process_email( - IMAP_SERVER, - EMAIL, - PASSWORD, - SENDER_EMAIL, - EMAIL_SUBJECT, - COLUMN_MAPPING, - skiprows=SKIPROWS, - ) - if not csv_data: - logging.warning("Nenhum e-mail encontrado com o assunto esperado.") - raise AirflowSkipException("Nenhum e-mail encontrado. Task ignorada.") - - logging.info( - "CSV processado com sucesso. Registros encontrados: %s", len(csv_data) - ) - return csv_data - except Exception as e: - logging.error("Erro no processamento dos emails: %s", str(e)) - raise - - def insert_data_to_db(**context: Dict[str, Any]) -> None: - try: - task_instance: Any = context["ti"] - csv_data: Any = task_instance.xcom_pull(task_ids="process_emails") - - if not csv_data: - logging.warning("Nenhum dado para inserir no banco.") - raise AirflowSkipException( - "Nenhum dado foi encontrado para inserção no BD" - ) - - df = pd.read_csv(io.StringIO(csv_data)) - data = df.to_dict(orient="records") - - for record in data: - record["dt_ingest"] = datetime.now().isoformat() - - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - - - db.insert_data( - data, - "orcamento_mcid_por_acao", - schema="siafi", - ) - logging.info("Dados inseridos com sucesso no banco de dados.") - except Exception as e: - logging.error("Erro ao inserir dados no banco: %s", str(e)) - raise - - process_emails_task = PythonOperator( - task_id="process_emails", - python_callable=process_email_data, - provide_context=True, - ) - - insert_to_db_task = PythonOperator( - task_id="insert_to_db", - python_callable=insert_data_to_db, - provide_context=True, - ) - - process_emails_task >> insert_to_db_task diff --git a/dags/data_ingest/tesouro_gerencial/mir/empenhos_tesouro_parlamentares_ingest_dag.py b/dags/data_ingest/tesouro_gerencial/mir/empenhos_tesouro_parlamentares_ingest_dag.py deleted file mode 100644 index 5b375b6e..00000000 --- a/dags/data_ingest/tesouro_gerencial/mir/empenhos_tesouro_parlamentares_ingest_dag.py +++ /dev/null @@ -1,158 +0,0 @@ -from typing import Dict, Any, List -from airflow import DAG -from airflow.operators.python import PythonOperator -from airflow.models import Variable -from airflow.models.param import Param -from datetime import datetime, timedelta -import logging -import json -from schedule_loader import get_dynamic_schedule -from cliente_email import fetch_email_with_zip, extract_csv_from_zip -from cliente_postgres import ClientPostgresDB -from postgres_helpers import get_postgres_conn - -# Configurações básicas da DAG -default_args = { - "owner": "Tiago", - "depends_on_past": False, - "retries": 1, - "retry_delay": timedelta(minutes=5), -} - -COLUMN_MAPPING = { - 0: "programa_governo", - 1: "programa_governo_descricao", - 2: "acao_governo", - 3: "acao_governo_descricao", - 4: "emissao_mes", - 5: "emissao_dia", - 6: "ne_ccor", - 7: "ne_num_processo", - 8: "ne_info_complementar", - 9: "ne_ccor_descricao", - 10: "doc_observacao", - 11: "natureza_despesa", - 12: "natureza_despesa_descricao", - 13: "ne_ccor_favorecido", - 14: "ne_ccor_favorecido_descricao", - 15: "ne_ccor_ano_emissao", - 16: "ptres", - 17: "fonte_recursos_detalhada", - 18: "fonte_recursos_detalhada_descricao", - 19: "despesas_empenhadas", - 20: "despesas_liquidadas", - 21: "despesas_pagas", - 22: "restos_a_pagar_inscritos", - 23: "restos_a_pagar_pagos", -} - -UNIQUE_KEY = [ - "ne_ccor", - "natureza_despesa", - "doc_observacao", - "ne_ccor_ano_emissao", - "emissao_dia", - "emissao_mes", - "despesas_empenhadas", - "despesas_liquidadas", - "despesas_pagas", -] - -EMAIL_SUBJECT = "notas_de_empenho_ano_atual" -SKIPROWS = 8 - -# Configurações da DAG -with DAG( - dag_id="email_tesouro_parlamentares_ingest", - default_args=default_args, - description="Processa anexos dos empenhos vindo do email, formata e insere no db", - schedule_interval=get_dynamic_schedule("empenhos_tesouro_parlamentares_ingest_dag"), - start_date=datetime(2023, 12, 1), - catchup=False, - params={ - "data_referencia": Param( - default=None, - type=["string", "null"], - title="Data de Referencia", - description=( - "Data para filtrar os e-mails recebidos (formato YYYY-MM-DD). " - "Se nao informado, usa o dia atual." - ), - ) - }, - tags=["MIR", "email", "empenhos", "tesouro", "parlamentares"], -) as dag: - - def _get_db_client() -> ClientPostgresDB: - return ClientPostgresDB(get_postgres_conn("postgres_mir")) - - def _insert_dataframe(df, db: ClientPostgresDB) -> int: - df = df[df["ne_ccor_ano_emissao"].astype(str).str.startswith("20")] - records = df.to_dict(orient="records") - for r in records: - r["dt_ingest"] = datetime.now().isoformat() - - db.insert_data( - records, - "empenhos_tesouro_parlamentares", - conflict_fields=UNIQUE_KEY, - primary_key=UNIQUE_KEY, - schema="siafi", - ) - return len(records) - - def fetch_and_ingest(**context: Dict[str, Any]) -> Dict[str, int]: - """Processa cada anexo e ingere imediatamente, evitando acúmulo em memória.""" - creds = json.loads(Variable.get("email_credentials")) - params = context.get("params", {}) - data_referencia = params.get("data_referencia") - - target_date = None - if data_referencia: - try: - target_date = datetime.strptime(data_referencia, "%Y-%m-%d").date() - except ValueError as exc: - raise ValueError( - "Parametro 'data_referencia' invalido. Use o formato YYYY-MM-DD." - ) from exc - - logging.info( - "Buscando e-mails para a data: %s", - target_date.isoformat() if target_date else "dia atual", - ) - - zip_payloads: List[bytes] = fetch_email_with_zip( - creds["imap_server"], - creds["email"], - creds["password"], - creds["sender_email"], - EMAIL_SUBJECT, - target_date=target_date, - ) - - if not zip_payloads: - logging.warning("Nenhum anexo ZIP encontrado.") - return {"attachments": 0, "records": 0} - - logging.info("Total de anexos ZIP encontrados: %s", len(zip_payloads)) - - db = _get_db_client() - total_records = 0 - - for idx, payload in enumerate(zip_payloads, 1): - df = extract_csv_from_zip(payload, COLUMN_MAPPING, SKIPROWS) - if df is not None: - count = _insert_dataframe(df, db) - total_records += count - logging.info("Anexo %s: %s registros inseridos", idx, count) - else: - logging.warning("Anexo %s ignorado (CSV inválido)", idx) - del df # Libera memória imediatamente - - logging.info("Total: %s anexos, %s registros", len(zip_payloads), total_records) - return {"attachments": len(zip_payloads), "records": total_records} - - PythonOperator( - task_id="fetch_and_ingest", - python_callable=fetch_and_ingest, - ) diff --git a/dags/data_ingest/tesouro_gerencial/nc_tesouro_ingest.dag.py b/dags/data_ingest/tesouro_gerencial/nc_tesouro_ingest.dag.py deleted file mode 100644 index db850e75..00000000 --- a/dags/data_ingest/tesouro_gerencial/nc_tesouro_ingest.dag.py +++ /dev/null @@ -1,240 +0,0 @@ -from typing import Dict, Any, cast -from airflow import DAG -from airflow.operators.python import PythonOperator -from airflow.models import Variable -from datetime import datetime, timedelta -import logging -import json -import pandas as pd -import io -from schedule_loader import get_dynamic_schedule -from cliente_email import fetch_and_process_email -from cliente_postgres import ClientPostgresDB -from postgres_helpers import get_postgres_conn - -# Configurações básicas da DAG -default_args = { - "owner": "Davi", - "depends_on_past": False, - "retries": 1, - "retry_delay": timedelta(minutes=5), -} - -# Mapeamento das colunas para as notas de crédito -COLUMN_MAPPING = { - 0: "emissao_mes", - 1: "emissao_dia", - 2: "nc", - 3: "nc_transferencia", - 4: "nc_fonte_recursos", - 5: "nc_fonte_recursos_descricao", - 6: "ptres", - 7: "nc_evento", - 8: "nc_evento_descricao", - 9: "ug_responsavel", - 10: "ug_responsavel_descricao", - 11: "natureza_despesa", - 12: "natureza_despesa_detalhada", - 13: "plano_interno", - 14: "plano_detalhado_descricao1", - 15: "plano_detalhado_descricao2", - 16: "favorecido_doc", - 17: "favorecido_doc_descricao", - 18: "nc_valor_linha", - 19: "movimento_liquido", -} - -# Configurações dos emails -EMAIL_CONFIGS = { - "enviadas": { - "subject": "notas_credito_enviadas_devolvidas_a_partir_de_2024", - "column_mapping": COLUMN_MAPPING, - "skiprows": 10, - }, - "recebidas": { - "subject": "notas_credito_recebidas_a_partir_de_2024", - "column_mapping": None, - "skiprows": 6, - }, -} - -# Configurações da DAG -with DAG( - dag_id="email_notas_credito_ingest", - default_args=default_args, - description="Processa anexos das NCs vindo de dois emails, formata e insere no db", - schedule_interval=get_dynamic_schedule("nc_tesouro_ingest_dag"), - start_date=datetime(2023, 12, 1), - catchup=False, - tags=["email", "ncs", "tesouro"], -) as dag: - - def process_email_data(email_type: str, **context: Dict[str, Any]) -> pd.DataFrame: - """ - Função genérica para processar emails de notas de crédito. - """ - config = EMAIL_CONFIGS[email_type] - creds_data = json.loads(Variable.get("email_credentials")) - creds = cast(Dict[str, str], creds_data) - config = cast(Dict[str, Any], config) - - try: - logging.info(f"Iniciando o processamento das NCs {email_type}") - csv_data = fetch_and_process_email( - creds["imap_server"], - creds["email"], - creds["password"], - creds["sender_email"], - config["subject"], - config["column_mapping"], - skiprows=config["skiprows"], - ) - - if not csv_data: - logging.warning(f"Nenhum e-mail encontrado para NCs {email_type}") - return pd.DataFrame() - - df = pd.read_csv(io.StringIO(csv_data)) - - # Se não tem mapeamento de colunas (recebidas), aplicar o mapeamento padrão - if config["column_mapping"] is None and not df.empty: - expected_columns = list(COLUMN_MAPPING.values()) - if len(df.columns) == len(expected_columns): - df.columns = pd.Index(expected_columns) - else: - logging.warning( - f"N coluna incompatível:{len(expected_columns)},{len(df.columns)}" - ) - - logging.info( - f"CSV de NCs {email_type} processado com sucesso: {len(df)} registros" - ) - return df - - except Exception as e: - logging.error( - f"Erro no processamento dos emails de NCs {email_type}: {str(e)}" - ) - raise - - def process_email_data_enviadas(**context: Dict[str, Any]) -> pd.DataFrame: - """Wrapper para processar emails enviadas.""" - return process_email_data("enviadas", **context) - - def process_email_data_recebidas(**context: Dict[str, Any]) -> pd.DataFrame: - """Wrapper para processar emails recebidas.""" - return process_email_data("recebidas", **context) - - def combine_data(**context: Dict[str, Any]) -> pd.DataFrame: - """ - Função para combinar os dados dos dois emails. - """ - try: - task_instance: Any = context["ti"] - df_enviadas = cast( - pd.DataFrame, task_instance.xcom_pull(task_ids="process_emails_enviadas") - ) - df_recebidas = cast( - pd.DataFrame, task_instance.xcom_pull(task_ids="process_emails_recebidas") - ) - - # Combinar DataFrames válidos - dfs = [ - df - for df in [df_enviadas, df_recebidas] - if df is not None and not df.empty - ] - - if not dfs: - logging.warning("Nenhum dado foi encontrado para combinar.") - return pd.DataFrame() - - # Combinar os DataFrames e adicionar dt_ingest - combined_df = pd.concat(dfs, ignore_index=True) - combined_df["dt_ingest"] = datetime.now().isoformat() - - logging.info(f"Dados combinados: {len(combined_df)} registros no total.") - return combined_df - - except Exception as e: - logging.error(f"Erro ao combinar os dados: {str(e)}") - raise - - def insert_data_to_db(**context: Dict[str, Any]) -> None: - """ - Função para inserir os dados no banco de dados. - """ - try: - task_instance: Any = context["ti"] - combined_df = task_instance.xcom_pull(task_ids="combine_data") - - if combined_df is None or combined_df.empty: - logging.warning("Nenhum dado para inserir no banco.") - return - - data = combined_df.to_dict(orient="records") - - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - - db.insert_data(data, "nc_tesouro", schema="siafi") - logging.info("Dados inseridos com sucesso no banco de dados.") - except Exception as e: - logging.error("Erro ao inserir dados no banco: %s", str(e)) - raise - - def clean_duplicates(**context: Dict[str, Any]) -> None: - """ - Task para remover duplicados da tabela 'siafi.pf_tesouro'. - """ - try: - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - db.remove_duplicates("nc_tesouro", COLUMN_MAPPING, schema="siafi") - - except Exception as e: - logging.error(f"Erro ao executar a limpeza de duplicados: {str(e)}") - raise - - # Tarefa 1: Processar os e-mails de notas de crédito enviadas/devolvidas - process_emails_enviadas_task = PythonOperator( - task_id="process_emails_enviadas", - python_callable=process_email_data_enviadas, - provide_context=True, - ) - - # Tarefa 2: Processar os e-mails de notas de crédito recebidas - process_emails_recebidas_task = PythonOperator( - task_id="process_emails_recebidas", - python_callable=process_email_data_recebidas, - provide_context=True, - ) - - # Tarefa 3: Combinar os dados dos dois emails - combine_data_task = PythonOperator( - task_id="combine_data", - python_callable=combine_data, - provide_context=True, - ) - - # Tarefa 4: Inserir os dados no banco de dados - insert_to_db_task = PythonOperator( - task_id="insert_to_db", - python_callable=insert_data_to_db, - provide_context=True, - ) - - # Tarefa 5: Limpar duplicados no banco de dados - clean_duplicates_task = PythonOperator( - task_id="clean_duplicates", - python_callable=clean_duplicates, - provide_context=True, - ) - - # Fluxo da DAG - ( - [process_emails_enviadas_task, process_emails_recebidas_task] - >> combine_data_task - >> insert_to_db_task - >> clean_duplicates_task - ) diff --git a/dags/data_ingest/tesouro_gerencial/pf_tesouro_ingest_dag.py b/dags/data_ingest/tesouro_gerencial/pf_tesouro_ingest_dag.py deleted file mode 100644 index dd094853..00000000 --- a/dags/data_ingest/tesouro_gerencial/pf_tesouro_ingest_dag.py +++ /dev/null @@ -1,249 +0,0 @@ -from typing import Dict, Any -from airflow import DAG -from airflow.operators.python import PythonOperator -from airflow.models import Variable -from datetime import datetime, timedelta -import logging -import json -import pandas as pd -import io -from schedule_loader import get_dynamic_schedule -from cliente_email import fetch_and_process_email -from cliente_postgres import ClientPostgresDB -from postgres_helpers import get_postgres_conn - -# Configurações básicas da DAG -default_args = { - "owner": "Davi", - "depends_on_past": False, - "retries": 1, - "retry_delay": timedelta(minutes=5), -} - -# Mapeamento das colunas para as programações financeiras -COLUMN_MAPPING = { - 0: "emissao_mes", - 1: "emissao_dia", - 2: "ug_emitente", - 3: "ug_emitente_descricao", - 4: "ug_favorecido", - 5: "ug_favorecido_descricao", - 6: "pf_evento", - 7: "pf_evento_descricao", - 8: "pf", - 9: "pf_inscricao", - 10: "pf_acao", - 11: "pf_acao_descricao", - 12: "pf_fonte_recursos", - 13: "pf_fonte_recursos_descricao", - 14: "pf_vinculacao_pagamento", - 15: "pf_vinculacao_pagamento_descricao", - 16: "pf_categoria_gasto", - 17: "pf_recurso", - 18: "pf_recurso_descricao", - 19: "doc_observacao", - 20: "pf_valor_linha", -} - -# Assuntos dos emails a serem processados -EMAIL_SUBJECT_ENVIADAS = "programacoes_financeiras_enviadas_devolvidas_a_partir_de_2024" -EMAIL_SUBJECT_RECEBIDAS = "programacoes_financeiras_recebidas_a_partir_de_2024" -SKIPROWS = 6 - -# Configurações da DAG -with DAG( - dag_id="email_programacoes_financeiras_ingest", - default_args=default_args, - description="Processa anexos das PFs vindo de dois emails, formata e insere no db", - schedule_interval=get_dynamic_schedule("pf_tesouro_ingest_dag"), - start_date=datetime(2023, 12, 1), - catchup=False, - tags=["email", "pfs", "tesouro"], -) as dag: - - def process_email_data_enviadas(**context: Dict[str, Any]) -> str: - """ - Função para processar os emails com programações financeiras enviadas. - """ - creds = json.loads(Variable.get("email_credentials")) - - EMAIL = creds["email"] - PASSWORD = creds["password"] - IMAP_SERVER = creds["imap_server"] - SENDER_EMAIL = creds["sender_email"] - - try: - logging.info( - "Iniciando o processamento dos emails de programações enviadas/devolvidas" - ) - csv_data = fetch_and_process_email( - IMAP_SERVER, - EMAIL, - PASSWORD, - SENDER_EMAIL, - EMAIL_SUBJECT_ENVIADAS, - COLUMN_MAPPING, - skiprows=SKIPROWS, - ) - if not csv_data: - logging.warning( - "Nenhum e-mail encontrado com o assunto de programações enviadas" - ) - return "" - - logging.info("CSV de PFs enviadas processado com sucesso.") - return csv_data - except Exception as e: - logging.error( - "Erro no processamento dos emails de programações enviadas: %s", - str(e), - ) - raise - - def process_email_data_recebidas(**context: Dict[str, Any]) -> str: - """ - Função para processar os emails com programações financeiras recebidas. - """ - creds = json.loads(Variable.get("email_credentials")) - - EMAIL = creds["email"] - PASSWORD = creds["password"] - IMAP_SERVER = creds["imap_server"] - SENDER_EMAIL = creds["sender_email"] - - try: - logging.info( - "Iniciando o processamento dos emails de programações recebidas..." - ) - csv_data = fetch_and_process_email( - IMAP_SERVER, - EMAIL, - PASSWORD, - SENDER_EMAIL, - EMAIL_SUBJECT_RECEBIDAS, - column_mapping=None, - skiprows=SKIPROWS, - ) - if not csv_data: - logging.warning( - "Nenhum e-mail encontrado com o assunto de programações recebidas." - ) - return "" - - logging.info("CSV de PFs recebidas processado com sucesso.") - return csv_data - except Exception as e: - logging.error( - "Erro no processamento dos emails de programações recebidas: %s", str(e) - ) - raise - - def combine_data(**context: Dict[str, Any]) -> str: - """ - Função para combinar os dados dos dois emails. - """ - try: - task_instance: Any = context["ti"] - enviadas_data = ( - task_instance.xcom_pull(task_ids="process_emails_enviadas") or "" - ) - recebidas_data = ( - task_instance.xcom_pull(task_ids="process_emails_recebidas") or "" - ) - - combined_data = enviadas_data + recebidas_data - - if combined_data: - logging.info("Dados combinados com sucesso.") - else: - logging.warning("Nenhum dado encontrado em ambos os emails.") - - return combined_data - except Exception as e: - logging.error(f"Erro ao combinar os dados: {str(e)}") - raise - - def insert_data_to_db(**context: Dict[str, Any]) -> None: - """ - Função para inserir os dados no banco de dados. - Os dados combinados são recuperados do XCom. - """ - try: - task_instance: Any = context["ti"] - combined_data = task_instance.xcom_pull(task_ids="combine_data") - - if not combined_data: - logging.warning("Nenhum dado para inserir no banco.") - return - - df = pd.read_csv(io.StringIO(combined_data)) - data = df.to_dict(orient="records") - - # Adicionar dt_ingest a cada registro - for record in data: - record["dt_ingest"] = datetime.now().isoformat() - - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - - db.insert_data(data, "pf_tesouro", schema="siafi") - logging.info("Dados inseridos com sucesso no banco de dados.") - except Exception as e: - logging.error("Erro ao inserir dados no banco: %s", str(e)) - raise - - def clean_duplicates(**context: Dict[str, Any]) -> None: - """ - Task para remover duplicados da tabela 'siafi.pf_tesouro'. - """ - try: - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - db.remove_duplicates("pf_tesouro", COLUMN_MAPPING, schema="siafi") - - except Exception as e: - logging.error(f"Erro ao executar a limpeza de duplicados: {str(e)}") - raise - - # Tarefa 1: Processar os e-mails de programações enviadas/devolvidas - process_emails_enviadas_task = PythonOperator( - task_id="process_emails_enviadas", - python_callable=process_email_data_enviadas, - provide_context=True, - ) - - # Tarefa 2: Processar os e-mails de programações recebidas - process_emails_recebidas_task = PythonOperator( - task_id="process_emails_recebidas", - python_callable=process_email_data_recebidas, - provide_context=True, - ) - - # Tarefa 3: Combinar os dados dos dois emails - combine_data_task = PythonOperator( - task_id="combine_data", - python_callable=combine_data, - provide_context=True, - ) - - # Tarefa 4: Inserir os dados no db - insert_to_db_task = PythonOperator( - task_id="insert_to_db", - python_callable=insert_data_to_db, - provide_context=True, - ) - - # Tarefa 5: Limpar duplicados no banco de dados - clean_duplicates_task = PythonOperator( - task_id="clean_duplicates", - python_callable=clean_duplicates, - provide_context=True, - ) - - # Fluxo da DAG - ( - [process_emails_enviadas_task, process_emails_recebidas_task] - >> combine_data_task - >> insert_to_db_task - >> clean_duplicates_task - ) diff --git a/dags/data_ingest/tesouro_gerencial/visao_orcamentaria_ingest.py b/dags/data_ingest/tesouro_gerencial/visao_orcamentaria_ingest.py deleted file mode 100644 index 5819781a..00000000 --- a/dags/data_ingest/tesouro_gerencial/visao_orcamentaria_ingest.py +++ /dev/null @@ -1,324 +0,0 @@ -from typing import Dict, Any, Optional, List -from airflow import DAG -from airflow.operators.python import PythonOperator -from airflow.models import Variable -from datetime import datetime, timedelta -import logging -import json -import pandas as pd -import io -import re -import zipfile -from schedule_loader import get_dynamic_schedule -from cliente_email import fetch_email_with_zip -from cliente_postgres import ClientPostgresDB -from postgres_helpers import get_postgres_conn - -# Configurações básicas da DAG -default_args = { - "owner": "Davi", - "depends_on_past": False, - "retries": 1, - "retry_delay": timedelta(minutes=5), -} - -# Mapeamento das colunas para visão orçamentária -COLUMN_MAPPING = { - 0: "unidade_orcamentaria", - 1: "unidade_orcamentaria_desc", - 2: "acao_governo", - 3: "acao_governo_desc", - 4: "programa_governo", - 5: "programa_governo_desc", - 6: "unidade_plano_orcamentario", - 7: "plano_orcamentario_1", - 8: "plano_orcamentario_2", - 9: "programa_plano_orcamentario", - 10: "acao_plano_orcamentario", - 11: "plano_orcamentario_6", - 12: "plano_orcamentario_desc", - 13: "elemento_despesa", - 14: "elemento_despesa_desc", - 15: "orgao_uge", - 16: "orgao_uge_desc", - 17: "uge_matriz_filial", - 18: "ug_executora", - 19: "ug_executora_desc", - 20: "projeto_inicial_loa", - 21: "dotacao_inicial", - 22: "dotacao_atualizada", - 23: "credito_disponivel", - 24: "despesas_empenhadas", - 25: "despesas_a_liquidar", - 26: "despesar_a_pagar", - 27: "despesas_pagas", - 28: "restos_a_pagar_inscritos", - 29: "restos_a_pagar_pagos", -} - -EMAIL_SUBJECT = "visao_orcamentaria_total_ipea" - -# Configurações da DAG -with DAG( - dag_id="visao_orcamentaria_ingest", - default_args=default_args, - description=( - "DAG processa anexos da visão orçamentária total IPEA " - "vindo do email, formata e insere no db" - ), - schedule_interval=get_dynamic_schedule("visao_orcamentaria_ingest"), - start_date=datetime(2023, 12, 1), - catchup=False, - tags=["email", "visao_orcamentaria", "tesouro"], -) as dag: - - def _is_valid_data_line(line: str, columns: List[str]) -> bool: - """Verifica se a linha contém dados válidos para processamento.""" - # Verifica se é linha de cabeçalho, separador ou vazia - header_indicators = [ - "Páginas:", - "Unidade Orçamentária", - '"Unidade Orçamentária"', - '"UG Executora"', - '"PROJETO INICIAL DA LOA"', - ] - - if ( - not line - or line.startswith(" ") - or len(columns) < 20 - or any(indicator in line for indicator in header_indicators) - ): - return False - - # Verifica se tem dados essenciais preenchidos - unidade_orc = columns[0].strip('"').strip() if columns else "" - elemento_desp = columns[13].strip('"').strip() if len(columns) > 13 else "" - - return bool( - unidade_orc - and unidade_orc not in ["", '""'] - and elemento_desp - and elemento_desp not in ["", '""'] - ) - - def _clean_value(value: str) -> str: - """ - Limpa e padroniza valores para inserção no banco. - Mantém todos os dados como TEXT para evitar problemas de conversão. - """ - if not value or value in ["nan", "NaN", "None", "null", ""]: - return "" - - # Remove aspas desnecessárias - cleaned = str(value).strip('"').strip() - - # Trata valores especiais - if cleaned in ["nan", "NaN", "None", "null"]: - return "" - - return cleaned - - def _process_data_block(data_lines: List[str], year: str) -> List[Dict[str, Any]]: - """Processa um bloco de dados de um ano específico.""" - block_data = [] - - for line in data_lines: - line = line.strip() - columns = line.split("\t") - - if not _is_valid_data_line(line, columns): - continue - - # Remove aspas e limpa colunas - columns = [col.strip('"').strip() for col in columns] - - # Cria registro com mapeamento de colunas e limpeza de valores - row_data = {} - for col_index, col_name in COLUMN_MAPPING.items(): - raw_value = columns[col_index] if col_index < len(columns) else "" - row_data[col_name] = _clean_value(raw_value) - - row_data["ano_exercicio"] = str(year) - block_data.append(row_data) - - return block_data - - def _parse_csv_by_year_blocks(csv_content: str) -> List[Dict[str, Any]]: - """ - Processa CSV organizando dados por blocos de ano. - - Lógica: - 1. Encontra linhas com "Ano Lançamento: XXXX" - 2. Pula as próximas 5 linhas (cabeçalhos) - 3. Processa os dados até encontrar o próximo bloco ou fim do arquivo - 4. Adiciona a coluna ano_exercicio com o ano extraído - """ - lines = csv_content.strip().split("\n") - processed_data = [] - current_year = None - data_start_index = None - - logging.info(f"Iniciando processamento do CSV com {len(lines)} linhas") - - for i, line in enumerate(lines): - year_match = re.search(r"Ano Lançamento:\s*(\d{4})", line) - - if year_match: - # Processa bloco anterior se existir - if current_year and data_start_index is not None: - data_lines = lines[ - data_start_index : i - 2 - ] # Deixa margem para linhas vazias - year_data = _process_data_block(data_lines, current_year) - logging.info( - f"Processados {len(year_data)} registros para o ano " - f"{current_year}" - ) - processed_data.extend(year_data) - - # Inicia novo bloco - current_year = year_match.group(1) - data_start_index = i + 6 # Pula 5 linhas após "Ano Lançamento:" - logging.info( - f"Iniciando processamento do ano {current_year} a partir da " - f"linha {data_start_index}" - ) - - # Processa o último bloco - if current_year and data_start_index is not None: - data_lines = lines[data_start_index:] - year_data = _process_data_block(data_lines, current_year) - logging.info( - f"Processados {len(year_data)} registros para o último ano " - f"{current_year}" - ) - processed_data.extend(year_data) - - logging.info( - f"Processamento concluído. Total de registros: {len(processed_data)}" - ) - return processed_data - - def process_email_data(**context: Dict[str, Any]) -> Optional[str]: - """Processa o email e retorna os dados formatados.""" - creds = json.loads(Variable.get("email_credentials")) - - try: - logging.info("Iniciando o processamento dos emails...") - - # Busca o email com attachments ZIP - zip_payload = fetch_email_with_zip( - creds["imap_server"], - creds["email"], - creds["password"], - creds["sender_email"], - EMAIL_SUBJECT, - ) - - if not zip_payload: - logging.warning("Nenhum e-mail encontrado com o assunto esperado.") - return None - - # Extrai o CSV do ZIP (UTF-16) - with zipfile.ZipFile(io.BytesIO(zip_payload)) as zip_file: - for file_name in zip_file.namelist(): - if file_name.endswith(".csv"): - raw_data = zip_file.read(file_name) - csv_content = raw_data.decode("utf-16") - break - else: - logging.warning("Nenhum arquivo CSV encontrado no ZIP.") - return None - - # Processa o CSV com a lógica de blocos por ano - processed_data = _parse_csv_by_year_blocks(csv_content) - - if not processed_data: - logging.warning("Nenhum dado foi processado do CSV.") - return None - - df = pd.DataFrame(processed_data) - - # Adicionar dt_ingest a cada registro - df["dt_ingest"] = datetime.now().isoformat() - - # Garantir que todos os valores sejam strings para evitar problemas de tipo - for col in df.columns: - df[col] = df[col].astype(str) - - csv_string = df.to_csv(index=False) - - logging.info( - f"CSV processado com sucesso. Dados encontrados: " - f"{len(processed_data)} registros" - ) - return csv_string - - except Exception as e: - logging.error(f"Erro no processamento dos emails: {str(e)}") - raise - - def insert_and_clean_data(**context: Dict[str, Any]) -> None: - """Insere os dados no banco e limpa duplicados.""" - try: - task_instance: Any = context["ti"] - csv_data: Any = task_instance.xcom_pull(task_ids="process_emails") - - if not csv_data: - logging.warning("Nenhum dado para inserir no banco.") - return - - df = pd.read_csv(io.StringIO(csv_data)) - - # Garantir que todos os valores sejam strings para evitar problemas de tipo - for col in df.columns: - df[col] = df[col].astype(str) - df[col] = df[col].replace(["nan", "NaN", "None"], "") - - data = df.to_dict(orient="records") - - if not data: - logging.warning( - "DataFrame está vazio após o processamento. Nada será inserido." - ) - return - - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - - # Dropa a tabela antes de inserir novos dados - db.drop_table_if_exists("visao_orcamentaria_total", schema="siafi") - logging.info("Tabela siafi.visao_orcamentaria_total dropada com sucesso.") - - # Insere os dados - db.insert_data( - data, - "visao_orcamentaria_total", - schema="siafi", - ) - - logging.info( - f"Dados inseridos com sucesso no banco de dados. Total: " - f"{len(data)} registros" - ) - - except Exception as e: - logging.error(f"Erro ao inserir dados: {str(e)}") - raise - - # Definição das tarefas - process_emails_task = PythonOperator( - task_id="process_emails", - python_callable=process_email_data, - provide_context=True, - ) - - insert_and_clean_task = PythonOperator( - task_id="insert_and_clean", - python_callable=insert_and_clean_data, - provide_context=True, - ) - - # Fluxo da DAG - process_emails_task >> insert_and_clean_task diff --git a/dags/data_ingest/transfere_gov/mir/notas_de_credito_ingest_mir_dag.py b/dags/data_ingest/transfere_gov/mir/notas_de_credito_ingest_mir_dag.py deleted file mode 100644 index a68379bc..00000000 --- a/dags/data_ingest/transfere_gov/mir/notas_de_credito_ingest_mir_dag.py +++ /dev/null @@ -1,51 +0,0 @@ -import logging -from airflow.decorators import dag, task -from datetime import datetime, timedelta -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_postgres import ClientPostgresDB -from cliente_ted import ClienteTed - - -@dag( - schedule_interval=get_dynamic_schedule("notas_de_credito_ingest_mir_dag"), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "owner": "Mateus", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["notas de credito", "ted_api", "MIR"], -) -def notas_de_credito_mir_dag() -> None: - @task - def fetch_and_store_notas_de_credito() -> None: - logging.info("Iniciando fetch_and_store_notas_de_credito") - - api = ClienteTed() - postgres_conn_str = get_postgres_conn("postgres_mir") - db = ClientPostgresDB(postgres_conn_str) - id_planos_acao = db.get_id_planos_acao() - - for id_plano_acao in id_planos_acao: - notas_de_credito = api.get_notas_de_credito_by_id_plano_acao(id_plano_acao) - if notas_de_credito: - for nota in notas_de_credito: - nota["dt_ingest"] = datetime.now().isoformat() - - db.insert_data( - notas_de_credito, - "notas_de_credito", - conflict_fields=["id_nota"], - primary_key=["id_nota"], - schema="transfere_gov", - ) - else: - logging.warning( - f"Nenhuma nota de crédito encontrada plano de ação {id_plano_acao}" - ) - - fetch_and_store_notas_de_credito() - -notas_de_credito_mir_dag() diff --git a/dags/data_ingest/transfere_gov/mir/plano_acao_ingest_mir_dag.py b/dags/data_ingest/transfere_gov/mir/plano_acao_ingest_mir_dag.py deleted file mode 100644 index b07eba23..00000000 --- a/dags/data_ingest/transfere_gov/mir/plano_acao_ingest_mir_dag.py +++ /dev/null @@ -1,56 +0,0 @@ -import logging -from airflow.decorators import dag, task -from datetime import datetime, timedelta -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_ted import ClienteTed -from cliente_postgres import ClientPostgresDB - - -@dag( - schedule_interval=get_dynamic_schedule("plano_acao_ingest_mir_dag"), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "owner": "Mateus", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["ted_api", "planos_acao", "MIR"], -) -def api_planos_acao_mir_dag() -> None: - - @task - def fetch_and_store_planos_acao() -> None: - logging.info("Starting api_planos_acao_dag DAG") - api = ClienteTed() - postgres_conn_str = get_postgres_conn("postgres_mir") - db = ClientPostgresDB(postgres_conn_str) - id_programas = db.get_id_programas() - - total_processed = 0 - for id_programa in id_programas: - planos_acao_data = api.get_planos_acao_by_id_programa(id_programa) - if planos_acao_data: - for plano in planos_acao_data: - plano["dt_ingest"] = datetime.now().isoformat() - - db.insert_data( - planos_acao_data, - "planos_acao", - primary_key=["id_plano_acao"], - conflict_fields=["id_plano_acao"], - schema="transfere_gov", - ) - - total_processed += 1 - if total_processed % 10 == 0: - logging.info(f"Processed {total_processed} planos de ação") - else: - logging.warning(f"No planos de ação found for id_programa: {id_programa}") - - logging.info(f"Completed processing {total_processed} planos de ação") - - fetch_and_store_planos_acao() - -api_planos_acao_mir_dag() \ No newline at end of file diff --git a/dags/data_ingest/transfere_gov/mir/programa_financeira_ingest_mir_dag.py b/dags/data_ingest/transfere_gov/mir/programa_financeira_ingest_mir_dag.py deleted file mode 100644 index 7d1a19f9..00000000 --- a/dags/data_ingest/transfere_gov/mir/programa_financeira_ingest_mir_dag.py +++ /dev/null @@ -1,55 +0,0 @@ -import logging -from airflow.decorators import dag, task -from datetime import datetime, timedelta -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_postgres import ClientPostgresDB -from cliente_ted import ClienteTed - - -@dag( - schedule_interval=get_dynamic_schedule("programacao_financeira_ingest_mir_dag"), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "owner": "Mateus", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["programacao_financeira", "ted_api", "MIR"], -) -def programacao_financeira_mir_dag() -> None: - @task - def fetch_and_store_programacao_financeira() -> None: - logging.info("Iniciando fetch_and_store_programacao_financeira") - - api = ClienteTed() - postgres_conn_str = get_postgres_conn("postgres_mir") - db = ClientPostgresDB(postgres_conn_str) - id_planos_acao = db.get_id_planos_acao() - - for id_plano_acao in id_planos_acao: - programacao_financeira = api.get_programacao_financeira_by_id_plano_acao( - id_plano_acao - ) - if programacao_financeira: - # Adicionar dt_ingest a cada item - for item in programacao_financeira: - item["dt_ingest"] = datetime.now().isoformat() - - db.insert_data( - programacao_financeira, - "programacao_financeira", - conflict_fields=["id_programacao"], - primary_key=["id_programacao"], - schema="transfere_gov", - ) - else: - logging.warning( - f"Nenhuma programação financeira encontrada " - f"plano de ação {id_plano_acao}" - ) - - fetch_and_store_programacao_financeira() - -programacao_financeira_mir_dag() \ No newline at end of file diff --git a/dags/data_ingest/transfere_gov/mir/programas_ingest_mir_dag.py b/dags/data_ingest/transfere_gov/mir/programas_ingest_mir_dag.py deleted file mode 100644 index 27ed8436..00000000 --- a/dags/data_ingest/transfere_gov/mir/programas_ingest_mir_dag.py +++ /dev/null @@ -1,55 +0,0 @@ -import logging -from airflow.decorators import dag, task -from airflow.models import Variable -from datetime import datetime, timedelta -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_ted import ClienteTed -from cliente_postgres import ClientPostgresDB - -@dag( - schedule_interval=get_dynamic_schedule("api_programas_ted_dag"), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "owner": "Mateus", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["ted_api", "programas", "MIR"], -) -def api_programas_ted_dag() -> None: - - @task - def fetch_and_ingest_programas() -> None: - logging.info("Iniciando extração de programas") - - api = ClienteTed() - postgres_conn_str = get_postgres_conn("postgres_mir") - db = ClientPostgresDB(postgres_conn_str) - - sigla_alvo = Variable.get("airflow_orgao_ted", default_var="MIR") - - logging.info(f"Filtrando programas pela sigla: {sigla_alvo}") - programas_data = api.get_programas_by_sigla_unidade_descentralizadora(sigla_alvo) - - if not programas_data: - logging.warning(f"Nenhum dado retornado para a sigla {sigla_alvo}") - return - - for programa in programas_data: - programa["dt_ingest"] = datetime.now().isoformat() - - db.insert_data( - programas_data, - "programas", - primary_key=["id_programa"], - conflict_fields=["id_programa"], - schema="transfere_gov", - ) - - logging.info(f"Sucesso: {len(programas_data)} programas inseridos/atualizados para {sigla_alvo}") - - fetch_and_ingest_programas() - -api_programas_ted_dag() \ No newline at end of file diff --git a/dags/data_ingest/transfere_gov/notas_de_credito_ingest_dag.py b/dags/data_ingest/transfere_gov/notas_de_credito_ingest_dag.py deleted file mode 100644 index b8af4b6e..00000000 --- a/dags/data_ingest/transfere_gov/notas_de_credito_ingest_dag.py +++ /dev/null @@ -1,53 +0,0 @@ -import logging -from airflow.decorators import dag, task -from datetime import datetime, timedelta -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_postgres import ClientPostgresDB -from cliente_ted import ClienteTed - - -@dag( - schedule_interval=get_dynamic_schedule("notas_de_credito_ingest_dag"), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "owner": "Davi", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["notas de credito", "ted_api"], -) -def notas_de_credito_dag() -> None: - @task - def fetch_and_store_notas_de_credito() -> None: - logging.info("Iniciando fetch_and_store_notas_de_credito") - - api = ClienteTed() - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - id_planos_acao = db.get_id_planos_acao() - - for id_plano_acao in id_planos_acao: - notas_de_credito = api.get_notas_de_credito_by_id_plano_acao(id_plano_acao) - if notas_de_credito: - # Adicionar dt_ingest a cada nota - for nota in notas_de_credito: - nota["dt_ingest"] = datetime.now().isoformat() - - db.insert_data( - notas_de_credito, - "notas_de_credito", - conflict_fields=["id_nota"], - primary_key=["id_nota"], - schema="transfere_gov", - ) - else: - logging.warning( - f"Nenhuma nota de crédito encontrada plano de ação {id_plano_acao}" - ) - - fetch_and_store_notas_de_credito() - - -dag_instance = notas_de_credito_dag() diff --git a/dags/data_ingest/transfere_gov/plano_acao_ingest_dag.py b/dags/data_ingest/transfere_gov/plano_acao_ingest_dag.py deleted file mode 100644 index 4ef35978..00000000 --- a/dags/data_ingest/transfere_gov/plano_acao_ingest_dag.py +++ /dev/null @@ -1,58 +0,0 @@ -import logging -from airflow.decorators import dag, task -from datetime import datetime, timedelta -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_ted import ClienteTed -from cliente_postgres import ClientPostgresDB - - -@dag( - schedule_interval=get_dynamic_schedule("plano_acao_ingest_dag"), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "owner": "Davi", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["ted_api", "planos_acao"], -) -def api_planos_acao_dag() -> None: - - @task - def fetch_and_store_planos_acao() -> None: - logging.info("Starting api_planos_acao_dag DAG") - api = ClienteTed() - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - id_programas = db.get_id_programas() - - total_processed = 0 - for id_programa in id_programas: - planos_acao_data = api.get_planos_acao_by_id_programa(id_programa) - if planos_acao_data: - # Adicionar dt_ingest a cada plano - for plano in planos_acao_data: - plano["dt_ingest"] = datetime.now().isoformat() - - db.insert_data( - planos_acao_data, - "planos_acao", - primary_key=["id_plano_acao"], - conflict_fields=["id_plano_acao"], - schema="transfere_gov", - ) - - total_processed += 1 - if total_processed % 10 == 0: - logging.info(f"Processed {total_processed} planos de ação") - else: - logging.warning(f"No planos de ação found for id_programa: {id_programa}") - - logging.info(f"Completed processing {total_processed} planos de ação") - - fetch_and_store_planos_acao() - - -dag_instance = api_planos_acao_dag() diff --git a/dags/data_ingest/transfere_gov/programa_beneficiario_ingest_dag.py b/dags/data_ingest/transfere_gov/programa_beneficiario_ingest_dag.py deleted file mode 100644 index c8e936f8..00000000 --- a/dags/data_ingest/transfere_gov/programa_beneficiario_ingest_dag.py +++ /dev/null @@ -1,57 +0,0 @@ -import logging -from airflow.decorators import dag, task -from datetime import datetime, timedelta -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_ted import ClienteTed -from cliente_postgres import ClientPostgresDB - - -@dag( - schedule_interval=get_dynamic_schedule("programa_beneficiario_ingest_dag"), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "owner": "Davi", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["ted_api", "programa_beneficiario"], -) -def api_programa_beneficiario_dag() -> None: - - @task - def fetch_and_store_programa_beneficiario() -> None: - logging.info("Starting api_programa_beneficiario_dag DAG") - api = ClienteTed() - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - tx_codigo_siorgs = "7" - - beneficiario = api.get_ted_by_programa_beneficiario(tx_codigo_siorgs) - if beneficiario: - logging.info( - f"Tipo de beneficiario: {type(beneficiario)}, Conteúdo: {beneficiario}" - ) - logging.info("Inserting beneficiario into PostgreSQL") - unique_id_programas = [ - {"id_programa": id_prog} - for id_prog in {b["id_programa"] for b in beneficiario} - ] - - db.insert_data( - unique_id_programas, - "programas", - primary_key=["id_programa"], - conflict_fields=["id_programa"], - schema="transfere_gov", - ) - else: - logging.warning( - f"No beneficiario found for tx_codigo_siorg: {tx_codigo_siorgs}" - ) - - fetch_and_store_programa_beneficiario() - - -dag_instace = api_programa_beneficiario_dag() diff --git a/dags/data_ingest/transfere_gov/programacao_financeira_ingest_dag.py b/dags/data_ingest/transfere_gov/programacao_financeira_ingest_dag.py deleted file mode 100644 index a86a0e26..00000000 --- a/dags/data_ingest/transfere_gov/programacao_financeira_ingest_dag.py +++ /dev/null @@ -1,56 +0,0 @@ -import logging -from airflow.decorators import dag, task -from datetime import datetime, timedelta -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_postgres import ClientPostgresDB -from cliente_ted import ClienteTed - - -@dag( - schedule_interval=get_dynamic_schedule("programacao_financeira_ingest_dag"), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "owner": "Davi", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["programacao_financeira", "ted_api"], -) -def programacao_financeira_dag() -> None: - @task - def fetch_and_store_programacao_financeira() -> None: - logging.info("Iniciando fetch_and_store_programacao_financeira") - - api = ClienteTed() - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - id_planos_acao = db.get_id_planos_acao() - - for id_plano_acao in id_planos_acao: - programacao_financeira = api.get_programacao_financeira_by_id_plano_acao( - id_plano_acao - ) - if programacao_financeira: - # Adicionar dt_ingest a cada item - for item in programacao_financeira: - item["dt_ingest"] = datetime.now().isoformat() - - db.insert_data( - programacao_financeira, - "programacao_financeira", - conflict_fields=["id_programacao"], - primary_key=["id_programacao"], - schema="transfere_gov", - ) - else: - logging.warning( - f"Nenhuma programação financeira encontrada " - f"plano de ação {id_plano_acao}" - ) - - fetch_and_store_programacao_financeira() - - -dag_instance = programacao_financeira_dag() diff --git a/dags/data_ingest/transfere_gov/programas_ingest_dag.py b/dags/data_ingest/transfere_gov/programas_ingest_dag.py deleted file mode 100644 index 5aeaaba1..00000000 --- a/dags/data_ingest/transfere_gov/programas_ingest_dag.py +++ /dev/null @@ -1,88 +0,0 @@ -import logging -from airflow.decorators import dag, task -from airflow.models import Variable -from datetime import datetime, timedelta -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_ted import ClienteTed -from cliente_postgres import ClientPostgresDB - - -@dag( - schedule_interval=get_dynamic_schedule("programas_ingest_dag"), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "owner": "Davi", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["ted_api", "programas"], -) -def api_programas_dag() -> None: - - @task - def fetch_and_update_programas() -> None: - logging.info("Starting api_programas_dag - Update Programs") - api = ClienteTed() - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - id_programas = db.get_id_programas() - - total_processed = 0 - for id_programa in id_programas: - programas_data = api.get_programa_by_id_programa(id_programa) - if programas_data and len(programas_data) > 0: - programa = programas_data[0] - programa["dt_ingest"] = datetime.now().isoformat() - - # Alter table to add any new columns needed - db.alter_table(programa, "programas", schema="transfere_gov") - - # Insert/update the program data - db.insert_data( - programas_data, - "programas", - primary_key=["id_programa"], - conflict_fields=["id_programa"], - schema="transfere_gov", - ) - - total_processed += 1 - if total_processed % 10 == 0: - logging.info(f"Processed {total_processed} programs") - else: - logging.warning(f"No program data found for id_programa: {id_programa}") - - logging.info(f"Completed processing {total_processed} programs") - - @task - def fetch_and_update_programas_by_sigla() -> None: - logging.info("Starting fetch_and_update_programas_by_sigla - IPEA") - api = ClienteTed() - postgres_conn_str = get_postgres_conn() - db = ClientPostgresDB(postgres_conn_str) - sigla = Variable.get("airflow_orgao", default_var="IPEA").upper() - programas_data = api.get_programas_by_sigla_unidade_descentralizadora(sigla) - if programas_data and len(programas_data) > 0: - for programa in programas_data: - programa["dt_ingest"] = datetime.now().isoformat() - db.alter_table(programa, "programas", schema="transfere_gov") - db.insert_data( - programas_data, - "programas", - primary_key=["id_programa"], - conflict_fields=["id_programa"], - schema="transfere_gov", - ) - logging.info(f"Inserted/updated {len(programas_data)} programas for IPEA") - else: - logging.warning( - "No programas data found for sigla_unidade_descentralizadora=IPEA" - ) - - fetch_and_update_programas() - fetch_and_update_programas_by_sigla() - - -dag_instance = api_programas_dag() diff --git a/dags/data_ingest/transferegov_emendas/documentos_habeis_especias_ingest_dag.py b/dags/data_ingest/transferegov_emendas/documentos_habeis_especias_ingest_dag.py deleted file mode 100644 index 3acee287..00000000 --- a/dags/data_ingest/transferegov_emendas/documentos_habeis_especias_ingest_dag.py +++ /dev/null @@ -1,71 +0,0 @@ -import logging -from airflow.decorators import dag, task -from datetime import datetime, timedelta -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_transferegov_emendas import ClienteTransfereGov -from cliente_postgres import ClientPostgresDB - - -@dag( - schedule_interval=get_dynamic_schedule("documentos_habeis_especiais_ingest_dag"), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "owner": "Tiago", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["transfere_gov_api", "documentos_especiais", "MIR"], -) -def api_documentos_habeis_especiais_dag() -> None: - """DAG para buscar e armazenar documentos hábeis especiais do Transfere Gov.""" - - @task - def fetch_and_store_documentos_habeis_especiais() -> None: - logging.info( - "[documentos_habeis_especiais_ingest_dag.py] Iniciando extração documentos " - "hábeis especiais" - ) - - api = ClienteTransfereGov() - postgres_conn_str = get_postgres_conn('postgres_mir') - db = ClientPostgresDB(postgres_conn_str) - - # Busca todos os documentos hábeis especiais com paginação automática - documentos_data = api.get_all_documentos_habeis_especiais(page_size=1000) - - if documentos_data and len(documentos_data) > 0: - # Adicionar dt_ingest a cada documento - for documento in documentos_data: - documento["dt_ingest"] = datetime.now().isoformat() - - # Inserir/atualizar dados no banco - logging.info( - f"[documentos_habeis_especiais_ingest_dag.py] Inserindo " - f"{len(documentos_data)} documentos hábeis especiais no " - f"schema transfere_gov" - ) - db.insert_data( - documentos_data, - "documentos_habeis_especiais", - conflict_fields=["id_dh"], - primary_key=["id_dh"], - schema="transferegov_emendas", - ) - - logging.info( - f"[documentos_habeis_especiais_ingest_dag.py] Concluído. " - f"Total de {len(documentos_data)} documentos hábeis especiais " - f"inseridos/atualizados" - ) - else: - logging.warning( - "[documentos_habeis_especiais_ingest_dag.py] Nenhum documento hábil " - "especial encontrado" - ) - - fetch_and_store_documentos_habeis_especiais() - - -dag_instance = api_documentos_habeis_especiais_dag() diff --git a/dags/data_ingest/transferegov_emendas/empenhos_especiais_ingest_dag.py b/dags/data_ingest/transferegov_emendas/empenhos_especiais_ingest_dag.py deleted file mode 100644 index 69542a48..00000000 --- a/dags/data_ingest/transferegov_emendas/empenhos_especiais_ingest_dag.py +++ /dev/null @@ -1,67 +0,0 @@ -import logging -from airflow.decorators import dag, task -from datetime import datetime, timedelta -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_transferegov_emendas import ClienteTransfereGov -from cliente_postgres import ClientPostgresDB - - -@dag( - schedule_interval=get_dynamic_schedule("empenhos_especiais_ingest_dag"), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "owner": "Leonardo e Tiago", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["transfere_gov_api", "empenhos_especiais", "MIR"], -) -def api_empenhos_especiais_dag() -> None: - """DAG para buscar e armazenar empenhos especiais do Transfere Gov.""" - - @task - def fetch_and_store_empenhos_especiais() -> None: - logging.info( - "[empenhos_especiais_ingest_dag.py] Iniciando extração de empenhos especiais" - ) - - api = ClienteTransfereGov() - postgres_conn_str = get_postgres_conn('postgres_mir') - db = ClientPostgresDB(postgres_conn_str) - - # Busca todos os documentos hábeis especiais com paginação automática - documentos_data = api.get_all_empenhos_especiais(page_size=1000) - - if documentos_data and len(documentos_data) > 0: - # Adicionar dt_ingest a cada documento - for documento in documentos_data: - documento["dt_ingest"] = datetime.now().isoformat() - - # Inserir/atualizar dados no banco - logging.info( - f"[empenhos_especiais_ingest_dag.py] Inserindo {len(documentos_data)} " - "empenhos especiais no schema transfere_gov" - ) - db.insert_data( - documentos_data, - "empenhos_especiais", - conflict_fields=["id_empenho"], - primary_key=["id_empenho"], - schema="transferegov_emendas", - ) - - logging.info( - f"[empenhos_especiais_ingest_dag.py] Concluído. Total de " - f"{len(documentos_data)} empenhos especiais inseridos/atualizados" - ) - else: - logging.warning( - "[empenhos_especiais_ingest_dag.py] Nenhum empenho especial encontrado" - ) - - fetch_and_store_empenhos_especiais() - - -dag_instance = api_empenhos_especiais_dag() diff --git a/dags/data_ingest/transferegov_emendas/executor_especial_ingest_dag.py b/dags/data_ingest/transferegov_emendas/executor_especial_ingest_dag.py deleted file mode 100644 index a2c7cbc5..00000000 --- a/dags/data_ingest/transferegov_emendas/executor_especial_ingest_dag.py +++ /dev/null @@ -1,74 +0,0 @@ -import logging -from airflow.decorators import dag, task -from datetime import datetime -from postgres_helpers import get_postgres_conn -from cliente_transferegov_emendas import ClienteTransfereGov -from cliente_postgres import ClientPostgresDB - - -@dag( - schedule_interval="@daily", - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "owner": "Mateus e Gabriel", - "retries": 0, - # "retry_delay": timedelta(minutes=5), - }, - tags=["transfere_gov_api", "planos_acao_especiais", "MIR"], -) -def api_executor_especial_dag() -> None: - """DAG para buscar e armazenar executores especiais do Transfere Gov de forma massiva.""" - - @task - def fetch_and_store_executores_especiais() -> None: - logging.info( - "[executores_especiais_ingest_dag.py] Iniciando extração massiva de executores especiais" - ) - - api = ClienteTransfereGov() - postgres_conn_str = get_postgres_conn("postgres_mir") - db = ClientPostgresDB(postgres_conn_str) - - executores_data = api.get_all_executores_especiais(limit=1000) - - if executores_data and len(executores_data) > 0: - timestamp_atual = datetime.now().isoformat() - - unique = {} - for row in executores_data: - key = (row["id_plano_acao"], row["id_executor"]) - unique[key] = row # se já existir, substitui e mantém apenas 1 - - executores_data = list(unique.values()) - - for executor in executores_data: - executor["dt_ingest"] = timestamp_atual - - logging.info( - f"[executores_especiais_ingest_dag.py] Inserindo {len(executores_data)} " - "executores no schema transferegov_emendas" - ) - - # Inserção/Update (Upsert) - db.insert_data( - executores_data, - "executor_especial", - conflict_fields=["id_plano_acao", "id_executor"], - primary_key=["id_plano_acao", "id_executor"], - schema="transferegov_emendas", - ) - - logging.info( - f"[executores_especiais_ingest_dag.py] Concluído. Total de " - f"{len(executores_data)} executores inseridos/atualizados" - ) - else: - logging.warning( - "[executores_especiais_ingest_dag.py] Nenhum executor especial encontrado na API" - ) - - fetch_and_store_executores_especiais() - - -api_executor_especial_dag() diff --git a/dags/data_ingest/transferegov_emendas/finalidade_especial_ingest_dag.py b/dags/data_ingest/transferegov_emendas/finalidade_especial_ingest_dag.py deleted file mode 100644 index 7e8222ca..00000000 --- a/dags/data_ingest/transferegov_emendas/finalidade_especial_ingest_dag.py +++ /dev/null @@ -1,78 +0,0 @@ -import logging -from airflow.decorators import dag, task -from datetime import datetime, timedelta -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_transferegov_emendas import ClienteTransfereGov -from cliente_postgres import ClientPostgresDB - - -@dag( - schedule_interval=get_dynamic_schedule("finalidade_especial_ingest_dag"), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "owner": "Tiago", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["transfere_gov_api", "finalidade_especial", "MIR"], -) -def api_finalidade_especial_dag() -> None: - """DAG para buscar e armazenar finalidades especiais do Transfere Gov.""" - - @task - def fetch_and_store_finalidade_especial() -> None: - logging.info( - "[finalidade_especial_ingest_dag.py] Iniciando extração finalidades especiais" - ) - - api = ClienteTransfereGov() - postgres_conn_str = get_postgres_conn('postgres_mir') - db = ClientPostgresDB(postgres_conn_str) - - # Busca todas as finalidades especiais com paginação automática - finalidades_data = api.get_all_finalidades_especiais(page_size=1000) - - if finalidades_data and len(finalidades_data) > 0: - # Adicionar dt_ingest a cada documento - for documento in finalidades_data: - documento["dt_ingest"] = datetime.now().isoformat() - - # Inserir/atualizar dados no banco - logging.info( - f"[finalidade_especial_ingest_dag.py] Inserindo " - f"{len(finalidades_data)} finalidades especiais no " - f"schema transfere_gov" - ) - db.insert_data( - finalidades_data, - "finalidades_especiais", - conflict_fields=[ - "id_executor", - "cd_area_politica_publica_tipo_pt", - "area_politica_publica_pt", - ], - primary_key=[ - "id_executor", - "cd_area_politica_publica_tipo_pt", - "area_politica_publica_pt", - ], - schema="transferegov_emendas", - ) - - logging.info( - f"[finalidade_especial_ingest_dag.py] Concluído. " - f"Total de {len(finalidades_data)} finalidades especiais " - f"inseridas/atualizadas" - ) - else: - logging.warning( - "[finalidade_especial_ingest_dag.py] Nenhuma finalidade especial " - "encontrada" - ) - - fetch_and_store_finalidade_especial() - - -api_finalidade_especial_dag() diff --git a/dags/data_ingest/transferegov_emendas/historico_pagamentos_especiais_ingest_dag.py b/dags/data_ingest/transferegov_emendas/historico_pagamentos_especiais_ingest_dag.py deleted file mode 100644 index a81d696e..00000000 --- a/dags/data_ingest/transferegov_emendas/historico_pagamentos_especiais_ingest_dag.py +++ /dev/null @@ -1,72 +0,0 @@ -import logging -from airflow.decorators import dag, task -from datetime import datetime, timedelta -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_transferegov_emendas import ClienteTransfereGov -from cliente_postgres import ClientPostgresDB - - -@dag( - schedule_interval=get_dynamic_schedule("historico_pagamentos_especiais_ingest_dag"), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "owner": "Tiago", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["transfere_gov_api", "historico_pagamentos_especiais", "MIR"], -) -def api_historico_pagamentos_especiais_dag() -> None: - """DAG para buscar e armazenar histórico de pagamentos especiais do Transfere Gov.""" - - @task - def fetch_and_store_historico_pagamentos_especiais() -> None: - logging.info( - "[historico_pagamentos_especiais_ingest_dag.py] Iniciando extração histórico " - "de pagamentos especiais" - ) - - api = ClienteTransfereGov() - postgres_conn_str = get_postgres_conn('postgres_mir') - db = ClientPostgresDB(postgres_conn_str) - - # Busca todos os documentos hábeis especiais com paginação automática - historico_data = api.get_all_historico_pagamentos_especiais(page_size=1000) - - if historico_data and len(historico_data) > 0: - # Adicionar dt_ingest a cada documento - for documento in historico_data: - documento["dt_ingest"] = datetime.now().isoformat() - - # Inserir/atualizar dados no banco - logging.info( - f"[historico_pagamentos_especiais_ingest_dag.py] Inserindo " - f"{len(historico_data)} registros de histórico de pagamentos especiais no " - f"schema transfere_gov" - ) - db.insert_data( - historico_data, - "historico_pagamentos_especiais", - conflict_fields=["id_historico_op_ob"], - primary_key=["id_historico_op_ob"], - schema="transferegov_emendas", - ) - - logging.info( - f"[historico_pagamentos_especiais_ingest_dag.py] Concluído. " - f"Total de {len(historico_data)} registros de histórico de pagamentos" - " especiais " - f"inseridos/atualizados" - ) - else: - logging.warning( - "[historico_pagamentos_especiais_ingest_dag.py] Nenhum registro de " - "histórico de pagamento especial encontrado" - ) - - fetch_and_store_historico_pagamentos_especiais() - - -api_historico_pagamentos_especiais_dag() diff --git a/dags/data_ingest/transferegov_emendas/metas_especiais_ingest_dag.py b/dags/data_ingest/transferegov_emendas/metas_especiais_ingest_dag.py deleted file mode 100644 index 07e84b08..00000000 --- a/dags/data_ingest/transferegov_emendas/metas_especiais_ingest_dag.py +++ /dev/null @@ -1,61 +0,0 @@ -import logging -from airflow.decorators import dag, task -from datetime import datetime, timedelta -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_transferegov_emendas import ClienteTransfereGov -from cliente_postgres import ClientPostgresDB - - -@dag( - schedule_interval=get_dynamic_schedule("metas_especiais_ingest_dag"), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "owner": "Tiago", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["transfere_gov_api", "metas_especiais", "MIR"], -) -def api_metas_especiais_dag() -> None: - """DAG para buscar e armazenar metas especiais do Transfere Gov.""" - - @task - def fetch_and_store_metas_especiais() -> None: - logging.info( - "[metas_especiais_ingest_dag.py] Iniciando extração de metas especiais" - ) - - api = ClienteTransfereGov() - postgres_conn_str = get_postgres_conn('postgres_mir') - db = ClientPostgresDB(postgres_conn_str) - - metas_data = api.get_all_metas_especiais() - - if not metas_data: - logging.warning( - "[metas_especiais_ingest_dag.py] Nenhuma meta especial encontrada" - ) - return - - for meta in metas_data: - meta["dt_ingest"] = datetime.now().isoformat() - - db.insert_data( - metas_data, - "metas_especiais", - conflict_fields=["id_meta"], - primary_key=["id_meta"], - schema="transferegov_emendas", - ) - - logging.info( - f"[metas_especiais_ingest_dag.py] Concluído. " - f"Total: {len(metas_data)} metas especiais inseridas/atualizadas" - ) - - fetch_and_store_metas_especiais() - - -api_metas_especiais_dag() diff --git a/dags/data_ingest/transferegov_emendas/ordem_bancaria_especial_ingest_dag.py b/dags/data_ingest/transferegov_emendas/ordem_bancaria_especial_ingest_dag.py deleted file mode 100644 index 7bf0f884..00000000 --- a/dags/data_ingest/transferegov_emendas/ordem_bancaria_especial_ingest_dag.py +++ /dev/null @@ -1,70 +0,0 @@ -import logging -from airflow.decorators import dag, task -from datetime import datetime, timedelta -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_transferegov_emendas import ClienteTransfereGov -from cliente_postgres import ClientPostgresDB - - -@dag( - schedule_interval=get_dynamic_schedule("ordem_bancaria_especial_ingest_dag"), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "owner": "Tiago", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["transfere_gov_api", "ordem_bancaria_especial", "MIR"], -) -def api_ordem_bancaria_especial_dag() -> None: - """DAG para buscar e armazenar ordens bancárias especiais do Transfere Gov.""" - - @task - def fetch_and_store_ordem_bancaria_especial() -> None: - logging.info( - "[ordem_bancaria_especial_ingest_dag.py] Iniciando extração ordens bancárias especiais" - ) - - api = ClienteTransfereGov() - postgres_conn_str = get_postgres_conn("postgres_mir") - db = ClientPostgresDB(postgres_conn_str) - - # Busca todas as ordens bancárias especiais com paginação automática - ordem_data = api.get_all_ordens_bancarias_especiais(page_size=1000) - - if ordem_data and len(ordem_data) > 0: - # Adicionar dt_ingest a cada documento - for documento in ordem_data: - documento["dt_ingest"] = datetime.now().isoformat() - - # Inserir/atualizar dados no banco - logging.info( - f"[ordem_bancaria_especial_ingest_dag.py] Inserindo " - f"{len(ordem_data)} ordens bancárias especiais no " - f"schema transfere_gov" - ) - db.insert_data( - ordem_data, - "ordens_bancarias_especiais", - conflict_fields=["id_op_ob"], - primary_key=["id_op_ob"], - schema="transferegov_emendas", - ) - - logging.info( - f"[ordem_bancaria_especial_ingest_dag.py] Concluído. " - f"Total de {len(ordem_data)} ordens bancárias especiais " - f"inseridas/atualizadas" - ) - else: - logging.warning( - "[ordem_bancaria_especial_ingest_dag.py] Nenhuma ordem bancária especial " - "encontrada" - ) - - fetch_and_store_ordem_bancaria_especial() - - -api_ordem_bancaria_especial_dag() diff --git a/dags/data_ingest/transferegov_emendas/plano_trabalho_especial_ingest_dag.py b/dags/data_ingest/transferegov_emendas/plano_trabalho_especial_ingest_dag.py deleted file mode 100644 index 559d084d..00000000 --- a/dags/data_ingest/transferegov_emendas/plano_trabalho_especial_ingest_dag.py +++ /dev/null @@ -1,67 +0,0 @@ -import logging -from airflow.decorators import dag, task -from datetime import datetime, timedelta -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_transferegov_emendas import ClienteTransfereGov -from cliente_postgres import ClientPostgresDB - - -@dag( - schedule_interval=get_dynamic_schedule("plano_trabalho_especial_ingest_dag"), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "owner": "Mateus", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["transfere_gov_api", "plano_trabalho", "MIR"], -) -def api_plano_trabalho_especial_dag() -> None: - """DAG para buscar e armazenar planos de trabalho especiais do Transfere Gov.""" - - @task - def fetch_and_store_plano_trabalho_especial() -> None: - logging.info( - "[plano_trabalho_especial_ingest_dag.py] Iniciando extração de " - "planos de trabalho especiais" - ) - - api = ClienteTransfereGov() - postgres_conn_str = get_postgres_conn("postgres_mir") - db = ClientPostgresDB(postgres_conn_str) - - plano_data = api.get_all_plano_trabalho_especial(page_size=1000) - - if plano_data and len(plano_data) > 0: - for item in plano_data: - item["dt_ingest"] = datetime.now().isoformat() - - logging.info( - f"[plano_trabalho_especial_ingest_dag.py] Inserindo " - f"{len(plano_data)} planos de trabalho no schema transferegov_emendas" - ) - - db.insert_data( - plano_data, - "plano_trabalho_especial", - conflict_fields=["id_plano_trabalho"], - primary_key=["id_plano_trabalho"], - schema="transferegov_emendas", - ) - - logging.info( - f"[plano_trabalho_especial_ingest_dag.py] Concluído. " - f"Total de {len(plano_data)} registros processados." - ) - else: - logging.warning( - "[plano_trabalho_especial_ingest_dag.py] Nenhum plano de trabalho " - "encontrado" - ) - - fetch_and_store_plano_trabalho_especial() - - -api_plano_trabalho_especial_dag() diff --git a/dags/data_ingest/transferegov_emendas/planos_acao_especiais_ingest_dag.py b/dags/data_ingest/transferegov_emendas/planos_acao_especiais_ingest_dag.py deleted file mode 100644 index d6675ec9..00000000 --- a/dags/data_ingest/transferegov_emendas/planos_acao_especiais_ingest_dag.py +++ /dev/null @@ -1,77 +0,0 @@ -import logging -from airflow.decorators import dag, task -from datetime import datetime, timedelta -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_transferegov_emendas import ClienteTransfereGov -from cliente_postgres import ClientPostgresDB - - -@dag( - schedule_interval=get_dynamic_schedule("planos_acao_especiais_ingest_dag"), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "owner": "Davi e Mateus", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["transfere_gov_api", "planos_acao_especiais", "MIR"], -) -def api_planos_acao_especiais_dag() -> None: - """DAG para buscar e armazenar planos de ação especiais do Transfere Gov.""" - - @task - def fetch_and_store_planos_acao_especiais() -> None: - logging.info( - "[planos_acao_especiais_ingest_dag.py] Iniciando extração de " - "planos de ação especiais" - ) - - api = ClienteTransfereGov() - postgres_conn_str = get_postgres_conn("postgres_mir") - db = ClientPostgresDB(postgres_conn_str) - - # Buscar IDs dos programas especiais - query = ( - "SELECT DISTINCT id_programa FROM transferegov_emendas.programas_especiais" - ) - programas_ids = db.execute_query(query) - - if not programas_ids: - logging.warning( - "[planos_acao_especiais_ingest_dag.py] Nenhum programa encontrado" - ) - return - - total_planos = 0 - for (id_programa,) in programas_ids: - logging.info( - f"[planos_acao_especiais_ingest_dag.py] Buscando planos de ação " - f"para programa {id_programa}" - ) - - planos_data = api.get_all_planos_acao_especiais_by_programa(id_programa) - - if planos_data: - for plano in planos_data: - plano["dt_ingest"] = datetime.now().isoformat() - - db.insert_data( - planos_data, - "planos_acao_especiais", - conflict_fields=["id_plano_acao"], - primary_key=["id_plano_acao"], - schema="transferegov_emendas", - ) - total_planos += len(planos_data) - - logging.info( - f"[planos_acao_especiais_ingest_dag.py] Concluído. " - f"Total: {total_planos} planos de ação inseridos/atualizados" - ) - - fetch_and_store_planos_acao_especiais() - - -dag_instance = api_planos_acao_especiais_dag() diff --git a/dags/data_ingest/transferegov_emendas/programas_especiais_ingest_dag.py b/dags/data_ingest/transferegov_emendas/programas_especiais_ingest_dag.py deleted file mode 100644 index 5aa38d37..00000000 --- a/dags/data_ingest/transferegov_emendas/programas_especiais_ingest_dag.py +++ /dev/null @@ -1,67 +0,0 @@ -import logging -from airflow.decorators import dag, task -from datetime import datetime, timedelta -from schedule_loader import get_dynamic_schedule -from postgres_helpers import get_postgres_conn -from cliente_transferegov_emendas import ClienteTransfereGov -from cliente_postgres import ClientPostgresDB - - -@dag( - schedule_interval=get_dynamic_schedule("programas_especiais_ingest_dag"), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "owner": "Davi e Mateus", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["transfere_gov_api", "programas_especiais", "MIR"], -) -def api_programas_especiais_dag() -> None: - """DAG para buscar e armazenar programas especiais do Transfere Gov.""" - - @task - def fetch_and_store_programas_especiais() -> None: - logging.info( - "[programas_especiais_ingest_dag.py] Iniciando extração programas especiais" - ) - - api = ClienteTransfereGov() - postgres_conn_str = get_postgres_conn("postgres_mir") - db = ClientPostgresDB(postgres_conn_str) - - # Busca todos os programas especiais com paginação automática - programas_data = api.get_all_programas_especiais(page_size=1000) - - if programas_data and len(programas_data) > 0: - # Adicionar dt_ingest a cada programa - for programa in programas_data: - programa["dt_ingest"] = datetime.now().isoformat() - - # Inserir/atualizar dados no banco - logging.info( - f"[programas_especiais_ingest_dag.py] Inserindo {len(programas_data)} " - "programas especiais no schema transfere_gov" - ) - db.insert_data( - programas_data, - "programas_especiais", - conflict_fields=["id_programa"], - primary_key=["id_programa"], - schema="transferegov_emendas", - ) - - logging.info( - f"[programas_especiais_ingest_dag.py] Concluído. Total de " - f"{len(programas_data)} programas especiais inseridos/atualizados" - ) - else: - logging.warning( - "[programas_especiais_ingest_dag.py] Nenhum programa especial encontrado" - ) - - fetch_and_store_programas_especiais() - - -dag_instance = api_programas_especiais_dag() diff --git a/dags/data_ingest/transferegov_emendas/relatorio_gestao_novo_especial_ingest_dag.py b/dags/data_ingest/transferegov_emendas/relatorio_gestao_novo_especial_ingest_dag.py deleted file mode 100644 index d026c908..00000000 --- a/dags/data_ingest/transferegov_emendas/relatorio_gestao_novo_especial_ingest_dag.py +++ /dev/null @@ -1,71 +0,0 @@ -import logging -from schedule_loader import get_dynamic_schedule -from airflow.decorators import dag, task -from datetime import datetime, timedelta -from postgres_helpers import get_postgres_conn -from cliente_transferegov_emendas import ClienteTransfereGov -from cliente_postgres import ClientPostgresDB - - -@dag( - schedule_interval=get_dynamic_schedule("relatorio_gestao_novo_especial_dag"), - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "owner": "Tiago", - "retries": 1, - "retry_delay": timedelta(minutes=5), - }, - tags=["transfere_gov_api", "relatorio_gestao_novo_especial", "MIR"], -) -def api_relatorio_gestao_novo_especial_dag() -> None: - """DAG para buscar e armazenar relatórios de gestão novo especial do Transfere Gov""" - - @task - def fetch_and_store_relatorios_gestao_novo_especial() -> None: - logging.info( - "[relatorio_gestao_novo_especial_dag.py] Iniciando extração relatórios de" - " gestão novo especial" - ) - - api = ClienteTransfereGov() - postgres_conn_str = get_postgres_conn("postgres_mir") - db = ClientPostgresDB(postgres_conn_str) - - # Busca todos os relatórios de gestão novo especial com paginação automática - relatorios_data = api.get_all_relatorios_gestao_novo_especial(page_size=1000) - - if relatorios_data and len(relatorios_data) > 0: - # Adicionar dt_ingest a cada relatório - for relatorio in relatorios_data: - relatorio["dt_ingest"] = datetime.now().isoformat() - - # Inserir/atualizar dados no banco - logging.info( - f"[relatorio_gestao_novo_especial_dag.py] Inserindo " - f"{len(relatorios_data)} relatórios de gestão no " - f"schema transfere_gov" - ) - db.insert_data( - relatorios_data, - "relatorios_gestao_novo_especial", - conflict_fields=["id_relatorio_gestao_novo"], - primary_key=["id_relatorio_gestao_novo"], - schema="transferegov_emendas", - ) - - logging.info( - f"[relatorio_gestao_novo_especial_dag.py] Concluído. " - f"Total de {len(relatorios_data)} relatórios de gestão novo especial " - f"inseridos/atualizados" - ) - else: - logging.info( - "[relatorio_gestao_novo_especial_dag.py] Nenhum relatório de gestão novo " - "especial encontrado" - ) - - fetch_and_store_relatorios_gestao_novo_especial() - - -api_relatorio_gestao_novo_especial_dag() diff --git a/dags/data_ingest/transferegov_emendas/reltorio_gestao_ingest.py b/dags/data_ingest/transferegov_emendas/reltorio_gestao_ingest.py deleted file mode 100644 index 011fb206..00000000 --- a/dags/data_ingest/transferegov_emendas/reltorio_gestao_ingest.py +++ /dev/null @@ -1,57 +0,0 @@ -import logging -from airflow.decorators import dag, task -from datetime import datetime -from postgres_helpers import get_postgres_conn -from cliente_transferegov_emendas import ClienteTransfereGov -from cliente_postgres import ClientPostgresDB - - -@dag( - schedule_interval="@daily", - start_date=datetime(2023, 1, 1), - catchup=False, - default_args={ - "owner": "Mateus", - "retries": 1, - }, - tags=["transfere_gov_api", "relatorio_gestao_especial", "MIR"], -) -def api_relatorio_gestao_especial_dag() -> None: - - @task - def fetch_and_store_relatorios() -> None: - logging.info("[relatorio_gestao] Iniciando extração massiva global...") - - api = ClienteTransfereGov() - postgres_conn_str = get_postgres_conn("postgres_mir") - db = ClientPostgresDB(postgres_conn_str) - - relatorios_data = api.get_all_relatorio_gestao_especial(page_size=1000) - - if not relatorios_data: - logging.warning("[relatorio_gestao] Nenhum relatório retornado da API.") - return - - timestamp_atual = datetime.now().isoformat() - - for row in relatorios_data: - row["dt_ingest"] = timestamp_atual - - logging.info( - f"[relatorio_gestao] Inserindo {len(relatorios_data)} registros no Postgres." - ) - - db.insert_data( - relatorios_data, - table_name="relatorio_gestao_especial", - conflict_fields=["id_relatorio_gestao"], - primary_key=["id_relatorio_gestao"], - schema="transferegov_emendas", - ) - - logging.info("[relatorio_gestao] Ingestão concluída com sucesso.") - - fetch_and_store_relatorios() - - -api_relatorio_gestao_especial_dag() diff --git a/dags/data_ingest/transfere_gov/minc/minc_api_anexos_relatorios_dag.py b/dags/data_ingest/transferegov_fundo_a_fundo/api_anexos_relatorios_dag.py similarity index 65% rename from dags/data_ingest/transfere_gov/minc/minc_api_anexos_relatorios_dag.py rename to dags/data_ingest/transferegov_fundo_a_fundo/api_anexos_relatorios_dag.py index 4d1a8ad1..119c4cbe 100644 --- a/dags/data_ingest/transfere_gov/minc/minc_api_anexos_relatorios_dag.py +++ b/dags/data_ingest/transferegov_fundo_a_fundo/api_anexos_relatorios_dag.py @@ -2,8 +2,8 @@ from datetime import datetime, timedelta from typing import Any -from airflow.decorators import dag, task -from airflow.operators.trigger_dagrun import TriggerDagRunOperator +from airflow.sdk import dag, task +from airflow.providers.standard.operators.trigger_dagrun import TriggerDagRunOperator from cliente_postgres import ClientPostgresDB from cliente_transferegov_fundo_a_fundo import ClienteTransfereGovBackend @@ -19,17 +19,17 @@ @dag( - dag_id="minc_api_anexos_relatorios_dag", - schedule_interval=None, + dag_id="api_anexos_relatorios_dag", + schedule=None, start_date=datetime(2023, 1, 1), catchup=False, default_args=default_args, - tags=["transfere_gov", "anexos", "raw"], + tags=["minc", "transferegov", "anexos", "raw"], ) -def minc_api_anexos_relatorios_dag() -> None: +def api_anexos_relatorios_dag() -> None: @task def fetch_anexos_relatorios() -> list[dict[str, Any]]: - logging.info("[minc_api_anexos_relatorios_dag.py] Iniciando extração de anexos de relatórios") + logging.info("[api_anexos_relatorios_dag.py] Iniciando extração de anexos de relatórios") db = ClientPostgresDB(get_postgres_conn()) ids_relatorios = db.get_id_relatorios_gestao( @@ -37,14 +37,14 @@ def fetch_anexos_relatorios() -> list[dict[str, Any]]: ) if not ids_relatorios: - raise ValueError("[minc_api_anexos_relatorios_dag.py] Nenhum relatório de gestão encontrado") + raise ValueError("[api_anexos_relatorios_dag.py] Nenhum relatório de gestão encontrado") api = ClienteTransfereGovBackend() anexos_data: list[dict[str, Any]] = [] for id_relatorio in ids_relatorios: logging.info( - "[minc_api_anexos_relatorios_dag.py] Buscando anexos para relatório ID: %s", + "[api_anexos_relatorios_dag.py] Buscando anexos para relatório ID: %s", id_relatorio, ) @@ -58,28 +58,28 @@ def fetch_anexos_relatorios() -> list[dict[str, Any]]: anexos_data.extend(anexos_raw) logging.info( - "[minc_api_anexos_relatorios_dag.py] Relatório %s: %d anexos encontrados", + "[api_anexos_relatorios_dag.py] Relatório %s: %d anexos encontrados", id_relatorio, len(anexos_raw), ) else: logging.warning( - "[minc_api_anexos_relatorios_dag.py] Nenhum anexo encontrado para relatório ID: %s", + "[api_anexos_relatorios_dag.py] Nenhum anexo encontrado para relatório ID: %s", id_relatorio, ) if not anexos_data: - raise ValueError("[minc_api_anexos_relatorios_dag.py] Nenhum anexo foi extraído") + raise ValueError("[api_anexos_relatorios_dag.py] Nenhum anexo foi extraído") logging.info( - "[minc_api_anexos_relatorios_dag.py] Extração concluída com %s registros", + "[api_anexos_relatorios_dag.py] Extração concluída com %s registros", len(anexos_data), ) return anexos_data @task def load_anexos_to_postgres(anexos_data: list[dict[str, Any]]) -> None: - logging.info("[minc_api_anexos_relatorios_dag.py] Iniciando carga no PostgreSQL") + logging.info("[api_anexos_relatorios_dag.py] Iniciando carga no PostgreSQL") db = ClientPostgresDB(get_postgres_conn()) db.insert_data( @@ -91,17 +91,17 @@ def load_anexos_to_postgres(anexos_data: list[dict[str, Any]]) -> None: ) logging.info( - "[minc_api_anexos_relatorios_dag.py] Carga concluída com %s registros", + "[api_anexos_relatorios_dag.py] Carga concluída com %s registros", len(anexos_data), ) trigger_download = TriggerDagRunOperator( task_id="trigger_download_anexos", - trigger_dag_id="ingestao_anexos_transferegov", + trigger_dag_id="download_anexos_transferegov_dag", wait_for_completion=False, ) load_anexos_to_postgres(fetch_anexos_relatorios()) >> trigger_download -minc_api_anexos_relatorios_dag() +api_anexos_relatorios_dag() diff --git a/dags/data_ingest/transfere_gov/minc/minc_api_planos_acao_dag.py b/dags/data_ingest/transferegov_fundo_a_fundo/api_planos_acao_dag.py similarity index 64% rename from dags/data_ingest/transfere_gov/minc/minc_api_planos_acao_dag.py rename to dags/data_ingest/transferegov_fundo_a_fundo/api_planos_acao_dag.py index fcb344fb..acd2f40b 100644 --- a/dags/data_ingest/transfere_gov/minc/minc_api_planos_acao_dag.py +++ b/dags/data_ingest/transferegov_fundo_a_fundo/api_planos_acao_dag.py @@ -2,9 +2,9 @@ from datetime import datetime, timedelta from typing import Any -from airflow.decorators import dag, task -from airflow.models import Variable -from airflow.operators.trigger_dagrun import TriggerDagRunOperator +from airflow.sdk import dag, task +from airflow.sdk import Variable +from airflow.providers.standard.operators.trigger_dagrun import TriggerDagRunOperator from cliente_postgres import ClientPostgresDB from cliente_transferegov_fundo_a_fundo import ClienteTransfereGov @@ -20,21 +20,21 @@ @dag( - dag_id="minc_api_planos_acao_dag", - schedule_interval=get_dynamic_schedule("minc_planos_acao_dag"), + dag_id="api_planos_acao_dag", + schedule=get_dynamic_schedule("api_planos_acao_dag"), start_date=datetime(2023, 1, 1), catchup=False, default_args=default_args, - tags=["transfere_gov", "planos_acao", "raw"], + tags=["minc", "transferegov", "planos_acao", "raw"], ) -def minc_api_planos_acao_dag() -> None: +def api_planos_acao_dag() -> None: @task def fetch_planos_acao() -> list[dict[str, Any]]: - logging.info("[minc_api_planos_acao_dag.py] Iniciando extração de planos de ação") + logging.info("[api_planos_acao_dag.py] Iniciando extração de planos de ação") ids_alvo = Variable.get( "transferegov_programas_ids", - default_var=[46, 47], + default=[46, 47], deserialize_json=True, ) @@ -43,7 +43,7 @@ def fetch_planos_acao() -> list[dict[str, Any]]: for id_programa in ids_alvo: logging.info( - "[minc_api_planos_acao_dag.py] Buscando planos de ação para programa ID: %s", + "[api_planos_acao_dag.py] Buscando planos de ação para programa ID: %s", id_programa, ) planos = api.get_planos_acao_by_programa(int(id_programa)) @@ -54,28 +54,28 @@ def fetch_planos_acao() -> list[dict[str, Any]]: planos_data.extend(planos) logging.info( - "[minc_api_planos_acao_dag.py] Programa %s: %d planos encontrados", + "[api_planos_acao_dag.py] Programa %s: %d planos encontrados", id_programa, len(planos), ) else: logging.warning( - "[minc_api_planos_acao_dag.py] Nenhum plano encontrado para programa ID: %s", + "[api_planos_acao_dag.py] Nenhum plano encontrado para programa ID: %s", id_programa, ) if not planos_data: - raise ValueError("[minc_api_planos_acao_dag.py] Nenhum plano de ação foi extraído") + raise ValueError("[api_planos_acao_dag.py] Nenhum plano de ação foi extraído") logging.info( - "[minc_api_planos_acao_dag.py] Extração concluída com %s registros", + "[api_planos_acao_dag.py] Extração concluída com %s registros", len(planos_data), ) return planos_data @task def load_planos_to_postgres(planos_data: list[dict[str, Any]]) -> None: - logging.info("[minc_api_planos_acao_dag.py] Iniciando carga no PostgreSQL") + logging.info("[api_planos_acao_dag.py] Iniciando carga no PostgreSQL") db = ClientPostgresDB(get_postgres_conn()) db.insert_data( @@ -87,17 +87,17 @@ def load_planos_to_postgres(planos_data: list[dict[str, Any]]) -> None: ) logging.info( - "[minc_api_planos_acao_dag.py] Carga concluída com %s registros", + "[api_planos_acao_dag.py] Carga concluída com %s registros", len(planos_data), ) trigger_relatorios = TriggerDagRunOperator( task_id="trigger_relatorios", - trigger_dag_id="minc_api_relatorios_gestao_dag", + trigger_dag_id="api_relatorios_gestao_dag", wait_for_completion=False, ) load_planos_to_postgres(fetch_planos_acao()) >> trigger_relatorios -minc_api_planos_acao_dag() +api_planos_acao_dag() diff --git a/dags/data_ingest/transfere_gov/minc/api_programas_dag.py b/dags/data_ingest/transferegov_fundo_a_fundo/api_programas_dag.py similarity index 71% rename from dags/data_ingest/transfere_gov/minc/api_programas_dag.py rename to dags/data_ingest/transferegov_fundo_a_fundo/api_programas_dag.py index 597086bc..a9018b47 100644 --- a/dags/data_ingest/transfere_gov/minc/api_programas_dag.py +++ b/dags/data_ingest/transferegov_fundo_a_fundo/api_programas_dag.py @@ -2,9 +2,9 @@ from datetime import datetime, timedelta from typing import Any -from airflow.decorators import dag, task -from airflow.models import Variable -from airflow.operators.trigger_dagrun import TriggerDagRunOperator +from airflow.sdk import dag, task +from airflow.sdk import Variable +from airflow.providers.standard.operators.trigger_dagrun import TriggerDagRunOperator from cliente_postgres import ClientPostgresDB from cliente_transferegov_fundo_a_fundo import ClienteTransfereGov @@ -20,20 +20,20 @@ @dag( - dag_id="minc_api_programas_dag", - schedule_interval=get_dynamic_schedule("minc_programas_ingest_dag"), + dag_id="api_programas_dag", + schedule=get_dynamic_schedule("api_programas_dag"), start_date=datetime(2023, 1, 1), catchup=False, default_args=default_args, - tags=["transfere_gov", "programas", "raw"], + tags=["minc", "transferegov", "programas", "raw"], ) -def minc_api_programas_dag() -> None: +def api_programas_dag() -> None: @task def fetch_programas() -> list[dict[str, Any]]: - logging.info("[minc_api_programas_dag.py] Iniciando extração de programas") + logging.info("[api_programas_dag.py] Iniciando extração de programas") ids_alvo = Variable.get( "transferegov_programas_ids", - default_var=[46, 47], + default=[46, 47], deserialize_json=True, ) @@ -54,17 +54,17 @@ def fetch_programas() -> list[dict[str, Any]]: ) if not programas_data: - raise ValueError("[minc_api_programas_dag.py] Nenhum programa foi extraído") + raise ValueError("[api_programas_dag.py] Nenhum programa foi extraído") logging.info( - "[minc_api_programas_dag.py] Extração concluída com %s registros", + "[api_programas_dag.py] Extração concluída com %s registros", len(programas_data), ) return programas_data @task def load_programas_to_postgres(programas_data: list[dict[str, Any]]) -> None: - logging.info("[minc_api_programas_dag.py] Iniciando carga no PostgreSQL") + logging.info("[api_programas_dag.py] Iniciando carga no PostgreSQL") db = ClientPostgresDB(get_postgres_conn()) db.insert_data( @@ -76,7 +76,7 @@ def load_programas_to_postgres(programas_data: list[dict[str, Any]]) -> None: ) logging.info( - "[minc_api_programas_dag.py] Carga concluída com %s registros", + "[api_programas_dag.py] Carga concluída com %s registros", len(programas_data), ) @@ -84,11 +84,11 @@ def load_programas_to_postgres(programas_data: list[dict[str, Any]]) -> None: trigger_planos_acao = TriggerDagRunOperator( task_id="trigger_planos_acao", - trigger_dag_id="minc_api_planos_acao_dag", + trigger_dag_id="api_planos_acao_dag", wait_for_completion=False, ) carga_finalizada >> trigger_planos_acao -minc_api_programas_dag() \ No newline at end of file +api_programas_dag() diff --git a/dags/data_ingest/transfere_gov/minc/minc_api_relatorios_gestao_dag.py b/dags/data_ingest/transferegov_fundo_a_fundo/api_relatorios_gestao_dag.py similarity index 66% rename from dags/data_ingest/transfere_gov/minc/minc_api_relatorios_gestao_dag.py rename to dags/data_ingest/transferegov_fundo_a_fundo/api_relatorios_gestao_dag.py index c445219b..d1f84495 100644 --- a/dags/data_ingest/transfere_gov/minc/minc_api_relatorios_gestao_dag.py +++ b/dags/data_ingest/transferegov_fundo_a_fundo/api_relatorios_gestao_dag.py @@ -2,8 +2,8 @@ from datetime import datetime, timedelta from typing import Any -from airflow.decorators import dag, task -from airflow.operators.trigger_dagrun import TriggerDagRunOperator +from airflow.sdk import dag, task +from airflow.providers.standard.operators.trigger_dagrun import TriggerDagRunOperator from cliente_postgres import ClientPostgresDB from cliente_transferegov_fundo_a_fundo import ClienteTransfereGov @@ -19,30 +19,30 @@ @dag( - dag_id="minc_api_relatorios_gestao_dag", - schedule_interval=None, + dag_id="api_relatorios_gestao_dag", + schedule=None, start_date=datetime(2023, 1, 1), catchup=False, default_args=default_args, - tags=["transfere_gov", "relatorios", "raw"], + tags=["minc", "transferegov", "relatorios", "raw"], ) -def minc_api_relatorios_gestao_dag() -> None: +def api_relatorios_gestao_dag() -> None: @task def fetch_relatorios_gestao() -> list[dict[str, Any]]: - logging.info("[minc_api_relatorios_gestao_dag.py] Iniciando extração de relatórios de gestão") + logging.info("[api_relatorios_gestao_dag.py] Iniciando extração de relatórios de gestão") db = ClientPostgresDB(get_postgres_conn()) ids_planos = db.get_id_planos_acao(schema="transferegov_fundo_a_fundo", table_name="raw_planos_acao") if not ids_planos: - raise ValueError("[minc_api_relatorios_gestao_dag.py] Nenhum plano de ação encontrado") + raise ValueError("[api_relatorios_gestao_dag.py] Nenhum plano de ação encontrado") api = ClienteTransfereGov() relatorios_data: list[dict[str, Any]] = [] for id_plano in ids_planos: logging.info( - "[minc_api_relatorios_gestao_dag.py] Buscando relatórios para plano ID: %s", + "[api_relatorios_gestao_dag.py] Buscando relatórios para plano ID: %s", id_plano, ) @@ -59,28 +59,28 @@ def fetch_relatorios_gestao() -> list[dict[str, Any]]: relatorios_data.extend(relatorios_finais) logging.info( - "[minc_api_relatorios_gestao_dag.py] Plano %s: %d relatórios FINAL encontrados", + "[api_relatorios_gestao_dag.py] Plano %s: %d relatórios FINAL encontrados", id_plano, len(relatorios_finais), ) else: logging.warning( - "[minc_api_relatorios_gestao_dag.py] Nenhum relatório encontrado para plano ID: %s", + "[api_relatorios_gestao_dag.py] Nenhum relatório encontrado para plano ID: %s", id_plano, ) if not relatorios_data: - raise ValueError("[minc_api_relatorios_gestao_dag.py] Nenhum relatório foi extraído") + raise ValueError("[api_relatorios_gestao_dag.py] Nenhum relatório foi extraído") logging.info( - "[minc_api_relatorios_gestao_dag.py] Extração concluída com %s registros", + "[api_relatorios_gestao_dag.py] Extração concluída com %s registros", len(relatorios_data), ) return relatorios_data @task def load_relatorios_to_postgres(relatorios_data: list[dict[str, Any]]) -> None: - logging.info("[minc_api_relatorios_gestao_dag.py] Iniciando carga no PostgreSQL") + logging.info("[api_relatorios_gestao_dag.py] Iniciando carga no PostgreSQL") db = ClientPostgresDB(get_postgres_conn()) db.insert_data( @@ -92,17 +92,17 @@ def load_relatorios_to_postgres(relatorios_data: list[dict[str, Any]]) -> None: ) logging.info( - "[minc_api_relatorios_gestao_dag.py] Carga concluída com %s registros", + "[api_relatorios_gestao_dag.py] Carga concluída com %s registros", len(relatorios_data), ) trigger_anexos = TriggerDagRunOperator( task_id="trigger_anexos", - trigger_dag_id="minc_api_anexos_relatorios_dag", + trigger_dag_id="api_anexos_relatorios_dag", wait_for_completion=False, ) load_relatorios_to_postgres(fetch_relatorios_gestao()) >> trigger_anexos -minc_api_relatorios_gestao_dag() +api_relatorios_gestao_dag() diff --git a/dags/data_ingest/transfere_gov/minc/minc_download_anexos_dag.py b/dags/data_ingest/transferegov_fundo_a_fundo/download_anexos_dag.py similarity index 92% rename from dags/data_ingest/transfere_gov/minc/minc_download_anexos_dag.py rename to dags/data_ingest/transferegov_fundo_a_fundo/download_anexos_dag.py index 430389cb..9cb0cccd 100644 --- a/dags/data_ingest/transfere_gov/minc/minc_download_anexos_dag.py +++ b/dags/data_ingest/transferegov_fundo_a_fundo/download_anexos_dag.py @@ -2,12 +2,12 @@ import logging import requests -from airflow.decorators import dag, task -from airflow.models import Variable -from airflow.operators.trigger_dagrun import TriggerDagRunOperator +from airflow.sdk import dag, task +from airflow.sdk import Variable +from airflow.providers.standard.operators.trigger_dagrun import TriggerDagRunOperator from airflow.providers.amazon.aws.hooks.s3 import S3Hook from airflow.providers.postgres.hooks.postgres import PostgresHook -from airflow.utils.trigger_rule import TriggerRule +from airflow.sdk import TriggerRule from datetime import datetime, timedelta @@ -21,12 +21,12 @@ @dag( - dag_id="ingestao_anexos_transferegov", + dag_id="download_anexos_transferegov_dag", default_args=default_args, - schedule_interval=None, + schedule=None, start_date=datetime(2023, 1, 1), catchup=False, - tags=["transferegov", "extracao", "anexos"], + tags=["minc", "transferegov", "extracao", "anexos"], ) def download_anexos_dag(): @@ -90,7 +90,7 @@ def baixar_e_salvar_anexos(pendente: dict): bucket_name = pendente["bucket"] # Hooks instanciados dentro da task — cada mapped task tem sua própria conexão - minio_conn_id = Variable.get("minio_conn_id", default_var="minio_default") + minio_conn_id = Variable.get("minio_conn_id", default="minio_default") s3_hook = S3Hook(aws_conn_id=minio_conn_id) pg_hook = PostgresHook(postgres_conn_id="postgres_default") @@ -145,7 +145,7 @@ def baixar_e_salvar_anexos(pendente: dict): # Usa ALL_DONE para que o trigger execute mesmo se alguns downloads falharem trigger_extracao = TriggerDagRunOperator( task_id="trigger_extracao_anexos", - trigger_dag_id="minc_extracao_anexos_dag", + trigger_dag_id="extracao_anexos_dag", wait_for_completion=False, trigger_rule=TriggerRule.ALL_DONE, ) diff --git a/dags/data_ingest/transfere_gov/minc/minc_extracao_anexos_dag.py b/dags/data_ingest/transferegov_fundo_a_fundo/extracao_anexos_dag.py similarity index 91% rename from dags/data_ingest/transfere_gov/minc/minc_extracao_anexos_dag.py rename to dags/data_ingest/transferegov_fundo_a_fundo/extracao_anexos_dag.py index 6f534ad3..4ce5d533 100644 --- a/dags/data_ingest/transfere_gov/minc/minc_extracao_anexos_dag.py +++ b/dags/data_ingest/transferegov_fundo_a_fundo/extracao_anexos_dag.py @@ -8,10 +8,10 @@ from typing import Any import pandas as pd -from airflow.decorators import dag, task -from airflow.models import Variable +from airflow.sdk import dag, task +from airflow.sdk import Variable from airflow.providers.amazon.aws.hooks.s3 import S3Hook -from airflow.utils.trigger_rule import TriggerRule +from airflow.sdk import TriggerRule from cliente_postgres import ClientPostgresDB from extracao_planilhas import extrair_tabela_raw, extrair_pnab, extrair_lpg, TimeoutLeituraError @@ -59,14 +59,14 @@ @dag( - dag_id="minc_extracao_anexos_dag", - schedule_interval=None, + dag_id="extracao_anexos_dag", + schedule=None, start_date=datetime(2023, 1, 1), catchup=False, default_args=default_args, - tags=["transfere_gov", "anexos", "planilhas", "raw"], + tags=["minc", "transferegov", "anexos", "planilhas", "raw"], ) -def minc_extracao_anexos_dag() -> None: +def extracao_anexos_dag() -> None: """DAG de extração de tabelas de anexos (XLSX/XLS/XLSM) para os programas LPG e PNAB, com Dynamic Task Mapping por **lote** de arquivos. @@ -104,7 +104,7 @@ def listar_arquivos_s3() -> list[list[dict[str, Any]]]: ids_validos = set( Variable.get( "transferegov_programas_ids", - default_var=[46, 47, 60, 61, 62], + default=[46, 47, 60, 61, 62], deserialize_json=True, ) ) @@ -118,7 +118,7 @@ def listar_arquivos_s3() -> list[list[dict[str, Any]]]: ids_prog = [ids_prog] if ids_prog and not any(i in ids_validos for i in ids_prog): logging.info( - "[minc_extracao_anexos_dag.py] Programa %s (IDs %s) " + "[extracao_anexos_dag.py] Programa %s (IDs %s) " "nao esta em transferegov_programas_ids — pulando", prog["nome_programa"], ids_prog, @@ -130,7 +130,7 @@ def listar_arquivos_s3() -> list[list[dict[str, Any]]]: prefix = prog.get("prefix", "") logging.info( - "[minc_extracao_anexos_dag.py] Listando arquivos para programa %s " + "[extracao_anexos_dag.py] Listando arquivos para programa %s " "no bucket s3://%s/%s", nome, bucket, @@ -144,7 +144,7 @@ def listar_arquivos_s3() -> list[list[dict[str, Any]]]: ) except Exception as exc: logging.warning( - "[minc_extracao_anexos_dag.py] Erro ao listar bucket %s: %s — pulando", + "[extracao_anexos_dag.py] Erro ao listar bucket %s: %s — pulando", bucket, exc, ) @@ -152,7 +152,7 @@ def listar_arquivos_s3() -> list[list[dict[str, Any]]]: if not keys: logging.warning( - "[minc_extracao_anexos_dag.py] Nenhum arquivo encontrado no " + "[extracao_anexos_dag.py] Nenhum arquivo encontrado no " "bucket %s para o programa %s", bucket, nome, @@ -167,7 +167,7 @@ def listar_arquivos_s3() -> list[list[dict[str, Any]]]: if ext not in extensoes_validas: if ext == ".ods": logging.info( - "[minc_extracao_anexos_dag.py] Arquivo .ods " + "[extracao_anexos_dag.py] Arquivo .ods " "ignorado (OOM risk): s3://%s/%s", bucket, key, @@ -190,7 +190,7 @@ def listar_arquivos_s3() -> list[list[dict[str, Any]]]: }) logging.info( - "[minc_extracao_anexos_dag.py] Programa %s: %d arquivos encontrados", + "[extracao_anexos_dag.py] Programa %s: %d arquivos encontrados", nome, sum( 1 @@ -201,7 +201,7 @@ def listar_arquivos_s3() -> list[list[dict[str, Any]]]: if not arquivos_meta: logging.warning( - "[minc_extracao_anexos_dag.py] Nenhum arquivo encontrado em nenhum programa" + "[extracao_anexos_dag.py] Nenhum arquivo encontrado em nenhum programa" ) return [] @@ -212,7 +212,7 @@ def listar_arquivos_s3() -> list[list[dict[str, Any]]]: ] logging.info( - "[minc_extracao_anexos_dag.py] %d arquivos → %d lotes de até %d arquivos", + "[extracao_anexos_dag.py] %d arquivos → %d lotes de até %d arquivos", len(arquivos_meta), len(chunks), _CHUNK_SIZE, @@ -248,7 +248,7 @@ def _processar_arquivo( tamanho_bytes = obj.content_length except Exception as exc: logging.warning( - "[minc_extracao_anexos_dag.py] Não foi possível obter " + "[extracao_anexos_dag.py] Não foi possível obter " "metadados de s3://%s/%s: %s — pulando arquivo", bucket, key, @@ -267,7 +267,7 @@ def _processar_arquivo( if tamanho_bytes > _MAX_FILE_BYTES: logging.warning( - "[minc_extracao_anexos_dag.py] Arquivo '%s' ignorado — " + "[extracao_anexos_dag.py] Arquivo '%s' ignorado — " "%.2f MB excede o limite de %d MB (OOM protection)", file_name, tamanho_mb, @@ -286,7 +286,7 @@ def _processar_arquivo( } logging.info( - "[minc_extracao_anexos_dag.py] Baixando s3://%s/%s (%.2f MB) para memória", + "[extracao_anexos_dag.py] Baixando s3://%s/%s (%.2f MB) para memória", bucket, key, tamanho_mb, @@ -297,7 +297,7 @@ def _processar_arquivo( file_content = obj.get()["Body"].read() except Exception as exc: logging.error( - "[minc_extracao_anexos_dag.py] Erro ao baixar s3://%s/%s: %s", + "[extracao_anexos_dag.py] Erro ao baixar s3://%s/%s: %s", bucket, key, exc, @@ -322,7 +322,7 @@ def _processar_arquivo( if nome_programa == "PNAB": # ── Fluxo PNAB: roteamento por aba ── logging.info( - "[minc_extracao_anexos_dag.py] Extraindo PNAB '%s' " + "[extracao_anexos_dag.py] Extraindo PNAB '%s' " "com roteamento por aba", file_name, ) @@ -335,7 +335,7 @@ def _processar_arquivo( elif nome_programa == "LPG": # ── Fluxo LPG: roteamento por template ── logging.info( - "[minc_extracao_anexos_dag.py] Extraindo LPG '%s' " + "[extracao_anexos_dag.py] Extraindo LPG '%s' " "com roteamento por template", file_name, ) @@ -356,7 +356,7 @@ def _processar_arquivo( regex_header = re.compile(file_meta["regex_header"], flags) logging.info( - "[minc_extracao_anexos_dag.py] Extraindo '%s' " + "[extracao_anexos_dag.py] Extraindo '%s' " "(fallback regex=%s, tabela=%s)", file_name, file_meta["regex_header"], @@ -401,7 +401,7 @@ def _processar_arquivo( colunas_removidas = colunas_antes - len(df_fb.columns) if linhas_removidas or colunas_removidas: logging.info( - "[minc_extracao_anexos_dag.py] Limpeza '%s' aba '%s': " + "[extracao_anexos_dag.py] Limpeza '%s' aba '%s': " "removidas %d/%d linhas, %d/%d colunas", file_name, res_fb["aba"], @@ -460,7 +460,7 @@ def _processar_arquivo( colunas_removidas = colunas_antes - len(df.columns) if linhas_removidas or colunas_removidas: logging.info( - "[minc_extracao_anexos_dag.py] Limpeza %s '%s' → %s: " + "[extracao_anexos_dag.py] Limpeza %s '%s' → %s: " "removidas %d/%d linhas, %d/%d colunas", nome_programa, file_name, @@ -473,7 +473,7 @@ def _processar_arquivo( if df.empty: logging.warning( - "[minc_extracao_anexos_dag.py] %s '%s' → %s: " + "[extracao_anexos_dag.py] %s '%s' → %s: " "descartada por estar vazia após limpeza", nome_programa, file_name, @@ -488,7 +488,7 @@ def _processar_arquivo( linhas = df.to_dict(orient="records") logging.info( - "[minc_extracao_anexos_dag.py] %s '%s' → %s: " + "[extracao_anexos_dag.py] %s '%s' → %s: " "inserindo %d registros em %s.%s", nome_programa, file_name, @@ -505,7 +505,7 @@ def _processar_arquivo( total_linhas += len(linhas) except Exception as exc_sub: logging.warning( - "[minc_extracao_anexos_dag.py] %s '%s' → subtabela " + "[extracao_anexos_dag.py] %s '%s' → subtabela " "'%s' falhou no INSERT: %s — continuando", nome_programa, file_name, @@ -515,7 +515,7 @@ def _processar_arquivo( continue logging.info( - "[minc_extracao_anexos_dag.py] %s '%s': %d subtabelas, " + "[extracao_anexos_dag.py] %s '%s': %d subtabelas, " "%d linhas inseridas", nome_programa, file_name, @@ -534,7 +534,7 @@ def _processar_arquivo( except TimeoutLeituraError as exc: logging.warning( - "[minc_extracao_anexos_dag.py] Arquivo '%s' ignorado por " + "[extracao_anexos_dag.py] Arquivo '%s' ignorado por " "lentidão (timeout %ds): %s", file_name, 120, @@ -551,7 +551,7 @@ def _processar_arquivo( except Exception as exc: logging.warning( - "[minc_extracao_anexos_dag.py] Arquivo ignorado por corrupção " + "[extracao_anexos_dag.py] Arquivo ignorado por corrupção " "ou erro de leitura: %s | Erro: %s", file_name, exc, @@ -614,7 +614,7 @@ def baixar_e_extrair(lote_de_arquivos: list[dict[str, Any]]) -> dict[str, Any]: # (segurança extra — o Worker não pode morrer) file_name = Path(file_meta.get("key", "unknown")).name logging.error( - "[minc_extracao_anexos_dag.py] Erro crítico no arquivo '%s': %s", + "[extracao_anexos_dag.py] Erro crítico no arquivo '%s': %s", file_name, exc, ) @@ -650,7 +650,7 @@ def baixar_e_extrair(lote_de_arquivos: list[dict[str, Any]]) -> dict[str, Any]: }) logging.info( - "[minc_extracao_anexos_dag.py] Lote finalizado: %d/%d OK, " + "[extracao_anexos_dag.py] Lote finalizado: %d/%d OK, " "%d erros download, %d erros extração, %d erros tamanho, " "%d erros críticos, %d linhas inseridas", resumo["n_sucesso"], @@ -714,7 +714,7 @@ def fechar_pipeline(resumos: list[dict[str, Any]]) -> dict[str, int]: if total_erros: logging.warning( - "[minc_extracao_anexos_dag.py] %d arquivos com erro de download, " + "[extracao_anexos_dag.py] %d arquivos com erro de download, " "%d com erro de extração, %d com erro de tamanho, " "%d com erro crítico", contagem["n_erro_download"], @@ -724,7 +724,7 @@ def fechar_pipeline(resumos: list[dict[str, Any]]) -> dict[str, int]: ) logging.info( - "[minc_extracao_anexos_dag.py] Pipeline finalizado: %d/%d arquivos OK " + "[extracao_anexos_dag.py] Pipeline finalizado: %d/%d arquivos OK " "(%d lotes), %d linhas inseridas no total", contagem["n_sucesso"], contagem["n_arquivos_total"], @@ -739,4 +739,4 @@ def fechar_pipeline(resumos: list[dict[str, Any]]) -> dict[str, int]: fechar_pipeline(resultados) -minc_extracao_anexos_dag() +extracao_anexos_dag() diff --git a/dags/dbt/ipea_cosmos_dag.py b/dags/dbt/minc_cosmos_dag.py old mode 100755 new mode 100644 similarity index 60% rename from dags/dbt/ipea_cosmos_dag.py rename to dags/dbt/minc_cosmos_dag.py index 10a62bfc..6bb71c94 --- a/dags/dbt/ipea_cosmos_dag.py +++ b/dags/dbt/minc_cosmos_dag.py @@ -1,30 +1,29 @@ import os from datetime import datetime -from cosmos import DbtDag, ProjectConfig, ProfileConfig, ExecutionConfig + +from cosmos import DbtDag, ExecutionConfig, ProfileConfig, ProjectConfig from cosmos.constants import DBT_LOG_PATH_ENVVAR + dbt_log_path = "/tmp/dbt_logs" os.makedirs(dbt_log_path, exist_ok=True) os.environ[DBT_LOG_PATH_ENVVAR] = dbt_log_path profile_config = ProfileConfig( - profiles_yml_filepath=f"{os.environ['AIRFLOW_REPO_BASE']}/dbt/ipea/profiles.yml", - profile_name="ipea", + profiles_yml_filepath=f"{os.environ['AIRFLOW_REPO_BASE']}/dbt/minc/profiles.yml", + profile_name="minc", target_name="prod", ) -my_cosmos_dag = DbtDag( - project_config=ProjectConfig(f"{os.environ['AIRFLOW_REPO_BASE']}/dbt/ipea"), +minc_cosmos_dag = DbtDag( + project_config=ProjectConfig(f"{os.environ['AIRFLOW_REPO_BASE']}/dbt/minc"), profile_config=profile_config, execution_config=ExecutionConfig( dbt_executable_path=f"{os.environ['AIRFLOW_REPO_BASE']}/.local/bin/dbt", ), - # Expressãp cron para agendar a execução do DAG diariamente às 01:00 - # Futuralmente isso pode ser substituído por um cronograma mais específico - # com dependências entre os DAGs - schedule_interval=" 0 1 * * *", + schedule="0 1 * * *", start_date=datetime(2025, 1, 1), catchup=False, - dag_id="ipea_cosmos_dag", + dag_id="minc_cosmos_dag", default_args={"retries": 2}, ) diff --git a/dags/dbt/mir_cosmos_dag.py b/dags/dbt/mir_cosmos_dag.py deleted file mode 100755 index cc890f2b..00000000 --- a/dags/dbt/mir_cosmos_dag.py +++ /dev/null @@ -1,30 +0,0 @@ -import os -from datetime import datetime -from cosmos import DbtDag, ProjectConfig, ProfileConfig, ExecutionConfig -from cosmos.constants import DBT_LOG_PATH_ENVVAR - -dbt_log_path = "/tmp/dbt_logs" # NOSONAR -os.makedirs(dbt_log_path, exist_ok=True) -os.environ[DBT_LOG_PATH_ENVVAR] = dbt_log_path - -profile_config = ProfileConfig( - profiles_yml_filepath=f"{os.environ['AIRFLOW_REPO_BASE']}/dbt/mir/profiles.yml", - profile_name="mir", - target_name="prod", -) - -my_cosmos_dag = DbtDag( - project_config=ProjectConfig(f"{os.environ['AIRFLOW_REPO_BASE']}/dbt/mir"), - profile_config=profile_config, - execution_config=ExecutionConfig( - dbt_executable_path=f"{os.environ['AIRFLOW_REPO_BASE']}/.local/bin/dbt", - ), - # Expressãp cron para agendar a execução do DAG diariamente às 01:00 - # Futuralmente isso pode ser substituído por um cronograma mais específico - # com dependências entre os DAGs - schedule_interval=" 0 1 * * *", - start_date=datetime(2025, 1, 1), - catchup=False, - dag_id="mir_cosmos_dag", - default_args={"retries": 2}, -) diff --git a/dbt/ipea/.user.yml b/dbt/ipea/.user.yml deleted file mode 100755 index 43198208..00000000 --- a/dbt/ipea/.user.yml +++ /dev/null @@ -1 +0,0 @@ -id: d025f823-c5b2-49c6-b826-226fb25f1ad8 diff --git a/dbt/ipea/dbt_project.yml b/dbt/ipea/dbt_project.yml deleted file mode 100755 index 17337daa..00000000 --- a/dbt/ipea/dbt_project.yml +++ /dev/null @@ -1,56 +0,0 @@ -name: 'ipea' - -version: 1.0.0 -config-version: 2 - -profile: ipea - -model-paths: ["models"] -analysis-paths: ["analyses"] -test-paths: ["tests"] -seed-paths: ["seeds"] -macro-paths: ["macros"] -snapshot-paths: ["snapshots"] - -clean-targets: - - "target" - - "dbt_packages" - - "logs" - -models: - ipea: - +database: analytics - metadata: - +materialized: incremental - +schema: metadata - contratos_dbt: - +materialized: table - +schema: contratos - bronze: - +materialized: incremental - views: - +materialized: view - pessoas_dbt: - +materialized: table - +schema: pessoas - views: - +materialized: view - ted_dbt: - +materialized: table - +schema: ted - views: - +materialized: view - orcamento_dbt: - +materialized: table - +schema: orcamento - views: - +materialized: view - # siape_dbt: - # +materialized: table - # +schema: siape - # views: - # +materialized: view - - -on-run-start: - - '{{create_udfs()}}' \ No newline at end of file diff --git a/dbt/ipea/descriptions.yml b/dbt/ipea/descriptions.yml deleted file mode 100644 index b1054f6d..00000000 --- a/dbt/ipea/descriptions.yml +++ /dev/null @@ -1,61 +0,0 @@ -version: 2 - -models: - contratos_dbt: - bronze: - - name: contratos - description: > - Tabela com informações sobre contratos, incluindo detalhes como o valor do contrato, a data de início e término, e o status do contrato. - Esta tabela é fundamental para entender a execução e o cumprimento dos contratos firmados. - A tabela é atualizada diariamente e contém dados de contratos firmados pelo IPEA. - - - name: cronogramas - description: > - Essa tabela contém informações sobre as despesas mensais programadas cada contrato. - - - name: faturas - description: > - Essa tabela contém informações sobre as faturas emitidas mensalmente de cada contrato. - - - name: empenhos - description: > - Essa tabela contém informações sobre os empenhos de cada contrato. - - - name: empenhos_tesouro - description: > - Essa tabela contém informações sobre os empenhos extraídos do SIAFI. - Essa tabela é atualizada diariamente. - - - name: estagios - description: > - Essa tabela contém informações sobre os evento de cada empenho discriminados por mês. - - silver: - - name: contratos_empenhos - description: > - Essa tabela contém informações sobre os empenhos de cada contrato, incluindo detalhes como o valor do empenho, a data de emissão e o status do empenho. - Esta tabela é fundamental para entender a execução - - pessoas_dbt: - - - ted_dbt: - - name: pf_tesouro - description: > - Dados das programações financeiras extraídas do SIAFI, com informações sobre o tipo de programação, a data de execução e o valor. - Essa tabela é atualizada diariamente. - - - name: empenhos_plano_acao - description: > - Dados dos empenhos extraídos do SIAFI, incluído o identificador do plano de ação. - Essa tabela é atualizada diariamente. - - - name: nc_plano_acao - description: > - Dados das notas de crédito extraídas do SIAFI, incluso o identificador do plano de ação. - Essa tabela é atualizada diariamente. - - - name: pf_plano_acao - description: > - Dados das programações financeiras extraídas do SIAFI, includo o identificador do plano de ação. - Essa tabela é atualizada diariamente. \ No newline at end of file diff --git a/dbt/ipea/macros/create_udfs.sql b/dbt/ipea/macros/create_udfs.sql deleted file mode 100644 index dd230cf5..00000000 --- a/dbt/ipea/macros/create_udfs.sql +++ /dev/null @@ -1,10 +0,0 @@ -{% macro create_udfs() %} - -create schema if not exists {{ target.schema }}; - - {{ create_f_parse_dates() }} - ; - {{ create_f_format_nc() }} - ; - -{% endmacro %} diff --git a/dbt/ipea/macros/data_quality/row_count_match.sql b/dbt/ipea/macros/data_quality/row_count_match.sql deleted file mode 100644 index f248e30c..00000000 --- a/dbt/ipea/macros/data_quality/row_count_match.sql +++ /dev/null @@ -1,14 +0,0 @@ -{% macro test_row_count_match(model, source_table, target_table) %} - with - source_count as (select count(*) as row_count from {{ source_table }}), - target_count as (select count(*) as row_count from {{ target_table }}), - comparison as ( - select - source_count.row_count as source_row_count, - target_count.row_count as target_row_count - from source_count, target_count - ) - select * - from comparison - where source_row_count != target_row_count -{% endmacro %} diff --git a/dbt/ipea/macros/data_quality/verificacao_tipagem.sql b/dbt/ipea/macros/data_quality/verificacao_tipagem.sql deleted file mode 100644 index 34c3d392..00000000 --- a/dbt/ipea/macros/data_quality/verificacao_tipagem.sql +++ /dev/null @@ -1,25 +0,0 @@ -{% macro test_verificacao_tipagem(model, nome_tabela, nome_coluna, tipo_esperado) %} - with - column_info as ( - select - table_schema, - table_name, -- Nome real da coluna no information_schema - column_name, -- Nome real da coluna no information_schema - data_type - from information_schema.columns - where - table_schema || '.' || table_name = '{{ nome_tabela }}' - and column_name = '{{ nome_coluna }}' - ), - comparison as ( - select - '{{ nome_tabela }}' as nome_tabela, - '{{ nome_coluna }}' as nome_coluna, - '{{ tipo_esperado }}' as tipo_esperado, - data_type as actual_type - from column_info - ) - select * - from comparison - where actual_type != tipo_esperado -{% endmacro %} diff --git a/dbt/ipea/macros/get_custom_schema.sql b/dbt/ipea/macros/get_custom_schema.sql deleted file mode 100755 index 79444e9a..00000000 --- a/dbt/ipea/macros/get_custom_schema.sql +++ /dev/null @@ -1,4 +0,0 @@ --- built-in schema generator -{% macro generate_schema_name(custom_schema_name, node) -%} - {{ generate_schema_name_for_env(custom_schema_name, node) }} -{%- endmacro %} diff --git a/dbt/ipea/macros/metadata/generate_metadata.sql b/dbt/ipea/macros/metadata/generate_metadata.sql deleted file mode 100644 index 8bfb115b..00000000 --- a/dbt/ipea/macros/metadata/generate_metadata.sql +++ /dev/null @@ -1,46 +0,0 @@ -{% macro get_model_metadata() %} -{# - Esta macro retorna os metadados do modelo atual. - Pode ser usada em post-hooks para registrar metadados automaticamente. -#} - SELECT - '{{ this.schema }}' AS schema_name, - '{{ this.name }}' AS table_name, - '{{ this.database }}' AS database_name, - ('{{ run_started_at }}'::TIMESTAMP AT TIME ZONE 'UTC' AT TIME ZONE 'America/Sao_Paulo') AS dt_transform, - '{{ invocation_id }}' AS run_id -{% endmacro %} - - -{% macro register_model_metadata() %} -{# - Esta macro registra os metadados do modelo em uma tabela central. - Deve ser usada como post-hook nos modelos que deseja rastrear. - - Uso no dbt_project.yml: - models: - ipea: - +post-hook: - - "{{ register_model_metadata() }}" -#} - - INSERT INTO {{ target.database }}.metadata.models_metadata ( - schema_name, - table_name, - database_name, - dt_transform, - run_id - ) - VALUES ( - '{{ this.schema }}', - '{{ this.name }}', - '{{ this.database }}', - ('{{ run_started_at }}'::TIMESTAMP AT TIME ZONE 'UTC' AT TIME ZONE 'America/Sao_Paulo'), - '{{ invocation_id }}' - ) - ON CONFLICT (schema_name, table_name) - DO UPDATE SET - dt_transform = EXCLUDED.dt_transform, - run_id = EXCLUDED.run_id; - -{% endmacro %} diff --git a/dbt/ipea/macros/parse_financial_value.sql b/dbt/ipea/macros/parse_financial_value.sql deleted file mode 100644 index 437b673c..00000000 --- a/dbt/ipea/macros/parse_financial_value.sql +++ /dev/null @@ -1,21 +0,0 @@ -{% macro parse_financial_value(column_name) %} - - case - when {{ column_name }} is null or trim({{ column_name }}) = '' - then 0.00::numeric(15, 2) - when {{ column_name }} like '%NaN%' - then 0.00::numeric(15, 2) - when {{ column_name }} like '(%' - then - regexp_replace( - replace(coalesce({{ column_name }}, '0'), '.', ''), - '(\()?(\d+),(\d+)(\))?', - '-\2.\3' - )::numeric(15, 2) - else - replace( - replace(coalesce({{ column_name }}, '0'), '.', ''), ',', '.' - )::numeric(15, 2) - end - -{% endmacro %} diff --git a/dbt/ipea/macros/schema.yml b/dbt/ipea/macros/schema.yml deleted file mode 100644 index 694f3b23..00000000 --- a/dbt/ipea/macros/schema.yml +++ /dev/null @@ -1,24 +0,0 @@ - -version: 2 - -macros: - - name: create_udfs - description: > - Função que cria as UDFs necessárias para o funcionamento do projeto. - Essa função deve ser chamada no início de cada run para garantir que todas as UDFs estejam disponíveis. - - - name: generate_schema_name - description: > - Função que gera o nome do schema a ser utilizado no projeto. - A função dentro desta macro é built-in do dbt. - - ## UDFS - - name: create_f_parse_dates - description: > - Função que cria a UDF f_parse_dates, que é utilizada para converter texto no formato MÊS(texto)/ANO(numero) em datas. - arguments: - - name: in_text - type: text - description: > - Texto a ser convertido em data. - O texto deve estar no formato MÊS(texto)/ANO(numero). Ex.: FEV/2024 -> 2024-02-01 \ No newline at end of file diff --git a/dbt/ipea/macros/udfs/f_format_nc.sql b/dbt/ipea/macros/udfs/f_format_nc.sql deleted file mode 100644 index f7a06c86..00000000 --- a/dbt/ipea/macros/udfs/f_format_nc.sql +++ /dev/null @@ -1,19 +0,0 @@ -{% macro create_f_format_nc() %} - create or replace function {{ target.schema }}.format_nc(in_text text) - returns text - as $$ - - with - - pre_process as ( - select left(in_text, 7) as prefix, - right(in_text, 4)::numeric as posfix - ) - - select concat(prefix, to_char(posfix, 'FM00000')) as result - from pre_process - - $$ - language sql - ; -{% endmacro %} diff --git a/dbt/ipea/macros/udfs/f_parse_dates.sql b/dbt/ipea/macros/udfs/f_parse_dates.sql deleted file mode 100644 index 3fd8693e..00000000 --- a/dbt/ipea/macros/udfs/f_parse_dates.sql +++ /dev/null @@ -1,44 +0,0 @@ --- Essa fun -{% macro create_f_parse_dates() %} - - create or replace function {{ target.schema }}.parse_date(in_text text) - returns date - as - $$ - - with - - split_column as ( - select - split_part(in_text, '/', 1) as mes, - split_part(in_text, '/', 2) as ano - ), - - fixed_month as ( - select - ano, - case - when mes = 'JAN' then '01' - when mes = 'FEV' then '02' - when mes = 'MAR' then '03' - when mes = 'ABR' then '04' - when mes = 'MAI' then '05' - when mes = 'JUN' then '06' - when mes = 'JUL' then '07' - when mes = 'AGO' then '08' - when mes = 'SET' then '09' - when mes = 'OUT' then '10' - when mes = 'NOV' then '11' - when mes = 'DEZ' then '12' - else mes end as mes_num - from split_column - ) - - select - (to_date(ano::numeric - 1 || '-' || '12', 'YYYY-MM') + (mes_num || ' months')::interval)::date as result - from fixed_month - $$ - language sql - ; - -{% endmacro %} diff --git a/dbt/ipea/models/contratos_dbt/bronze/contratos.sql b/dbt/ipea/models/contratos_dbt/bronze/contratos.sql deleted file mode 100755 index 8d38922d..00000000 --- a/dbt/ipea/models/contratos_dbt/bronze/contratos.sql +++ /dev/null @@ -1,123 +0,0 @@ -{{ config(materialized="table") }} - -with - contratos_raw as ( - select - -- Conversão de tipos e formatação de colunas - cast(id as text) as id, - receita_despesa, - numero, - contratante__orgao_origem__codigo, - contratante__orgao_origem__nome, - contratante__orgao_origem__unidade_gestora_origem__codigo, - contratante__orgao_origem__unidade_gestora_origem__nome_resumido, - contratante__orgao_origem__unidade_gestora_origem__nome, - contratante__orgao_origem__unidade_gestora_origem__sisg, - contratante__orgao_origem__unidade_gestora_origem__utiliza_siafi, - contratante__orgao_origem__unidade_gestora_origem__utiliza_antecip, - contratante__orgao__codigo, - contratante__orgao__nome, - contratante__orgao__unidade_gestora__codigo, - contratante__orgao__unidade_gestora__nome_resumido, - contratante__orgao__unidade_gestora__nome, - contratante__orgao__unidade_gestora__sisg, - contratante__orgao__unidade_gestora__utiliza_siafi, - contratante__orgao__unidade_gestora__utiliza_antecipagov, - fornecedor__tipo as fornecedor_tipo, - fornecedor__nome as fornecedor_nome, - codigo_tipo as codigo_tipo, - tipo, - subtipo, - prorrogavel, - situacao, - justificativa_inativo, - categoria, - subcategoria, - unidades_requisitantes, - objeto, - amparo_legal, - informacao_complementar, - codigo_modalidade, - modalidade, - unidade_compra as unidade_compra, - licitacao_numero, - sistema_origem_licitacao, - cast(num_parcelas as int) as num_parcelas, - cast( - replace( - replace(cast(valor_inicial as text), '.', ''), ',', '.' - ) as numeric(15, 2) - ) as valor_inicial, - -- Tratar valores nulos ou inválidos nas colunas de data - cast( - replace( - replace(cast(valor_global as text), '.', ''), ',', '.' - ) as numeric(15, 2) - ) as valor_global, - cast( - replace( - replace(cast(valor_parcela as text), '.', ''), ',', '.' - ) as numeric(15, 2) - ) as valor_parcela, - cast( - replace( - replace(cast(valor_acumulado as text), '.', ''), ',', '.' - ) as numeric(15, 2) - ) as valor_acumulado, - regexp_replace( - fornecedor__cnpj_cpf_idgener, '[^0-9A-Za-z]', '', 'g' - ) as fornecedor_cnpj_cpf_idgener, - regexp_replace(processo, '[^0-9A-Za-z]', '', 'g') as processo, - -- Conversão de valores numéricos para FLOAT ou INT - case - when data_assinatura is null - then null - when - data_assinatura is not null - and cast(data_assinatura as text) ~ '^\d{4}-\d{2}-\d{2}$' - -- Retorna NULL se não for uma data válida - then to_date(cast(data_assinatura as text), 'YYYY-MM-DD') - end as data_assinatura, - case - when data_publicacao is null - then null - when - data_publicacao is not null - and cast(data_publicacao as text) ~ '^\d{4}-\d{2}-\d{2}$' - -- Retorna NULL se não for uma data válida - then to_date(cast(data_publicacao as text), 'YYYY-MM-DD') - end as data_publicacao, - case - when data_proposta_comercial is null - then null - when - data_proposta_comercial is not null - and cast(data_proposta_comercial as text) ~ '^\d{4}-\d{2}-\d{2}$' - then - -- Retorna NULL se não for uma data válida - to_date(cast(data_proposta_comercial as text), 'YYYY-MM-DD') - end as data_proposta_comercial, - case - when vigencia_inicio is null - then null - when - vigencia_inicio is not null - and cast(vigencia_inicio as text) ~ '^\d{4}-\d{2}-\d{2}$' - -- Retorna NULL se não for uma data válida - then to_date(cast(vigencia_inicio as text), 'YYYY-MM-DD') - end as vigencia_inicio, - case - when vigencia_fim is null - then null - when - vigencia_fim is not null - and cast(vigencia_fim as text) ~ '^\d{4}-\d{2}-\d{2}$' - -- Retorna NULL se não for uma data válida - then to_date(cast(vigencia_fim as text), 'YYYY-MM-DD') - end as vigencia_fim, - (dt_ingest || '-03:00')::timestamptz as dt_ingest - from {{ source("compras_gov", "contratos") }} - ) -- - -select * -from contratos_raw diff --git a/dbt/ipea/models/contratos_dbt/bronze/cronogramas.sql b/dbt/ipea/models/contratos_dbt/bronze/cronogramas.sql deleted file mode 100644 index ba0da19f..00000000 --- a/dbt/ipea/models/contratos_dbt/bronze/cronogramas.sql +++ /dev/null @@ -1,24 +0,0 @@ -{{ config(materialized="table") }} - -with - cronogramas as ( - select - id::integer as id, - contrato_id::integer as contrato_id, - tipo::text as tipo, - numero::text as numero, - receita_despesa::text as receita_despesa, - observacao::text as observacao, - mesref::integer as mesref, - anoref::integer as anoref, - retroativo::text as retroativo, - replace(replace(valor::text, '.', ''), ',', '.')::numeric(15, 2) as valor, - vencimento::date as vencimento, - (dt_ingest || '-03:00')::timestamptz as dt_ingest - from {{ source("compras_gov", "cronograma") }} - ), - - distinct_cronogramas as (select distinct * from cronogramas) - -select * -from distinct_cronogramas diff --git a/dbt/ipea/models/contratos_dbt/bronze/empenhos.sql b/dbt/ipea/models/contratos_dbt/bronze/empenhos.sql deleted file mode 100755 index 1bb6ee31..00000000 --- a/dbt/ipea/models/contratos_dbt/bronze/empenhos.sql +++ /dev/null @@ -1,58 +0,0 @@ -{{ config(materialized="table") }} - -with - empenhos as ( - select - id::text as id, - contrato_id::text as contrato_id, - unidade_gestora, - gestao, - numero as nota_empenho, - credor, - fonte_recurso, - programa_trabalho, - planointerno, - naturezadespesa, - informacao_complementar, - sistema_origem, - links__documento_pagamento as links_documento_pagamento, - credor_obj__tipo as credor_obj_tipo, - credor_obj__cnpj_cpf_idgener as credor_obj_cnpj_cpf_idgener, - credor_obj__nome as credor_obj_nome, - - -- Tratar valores nulos ou inválidos nas colunas de data - replace(replace(empenhado::text, '.', ''), ',', '.')::numeric( - 15, 2 - ) as empenhado, - - -- Conversão de valores numéricos para FLOAT - replace(replace(aliquidar::text, '.', ''), ',', '.')::numeric( - 15, 2 - ) as aliquidar, - replace(replace(liquidado::text, '.', ''), ',', '.')::numeric( - 15, 2 - ) as liquidado, - replace(replace(pago::text, '.', ''), ',', '.')::numeric(15, 2) as pago, - replace(replace(rpinscrito::text, '.', ''), ',', '.')::numeric( - 15, 2 - ) as rpinscrito, - replace(replace(rpaliquidar::text, '.', ''), ',', '.')::numeric( - 15, 2 - ) as rpaliquidar, - replace(replace(rpliquidado::text, '.', ''), ',', '.')::numeric( - 15, 2 - ) as rpliquidado, - replace(replace(rppago::text, '.', ''), ',', '.')::numeric(15, 2) as rppago, - case - when - data_emissao is not null - and data_emissao::text ~ '^\d{4}-\d{2}-\d{2}$' - -- Retorna NULL se não for uma data válida - then to_date(data_emissao::text, 'YYYY-MM-DD') - end as data_emissao, - (dt_ingest || '-03:00')::timestamptz as dt_ingest - from {{ source("compras_gov", "empenhos") }} - ) - -select * -from empenhos diff --git a/dbt/ipea/models/contratos_dbt/bronze/empenhos_tesouro.sql b/dbt/ipea/models/contratos_dbt/bronze/empenhos_tesouro.sql deleted file mode 100755 index f5efa88f..00000000 --- a/dbt/ipea/models/contratos_dbt/bronze/empenhos_tesouro.sql +++ /dev/null @@ -1,49 +0,0 @@ -{{ - config( - unique_key=[ - "ne_ccor", - "natureza_despesa", - "doc_observacao", - "ne_ccor_ano_emissao", - "emissao_dia", - "emissao_mes", - "despesas_empenhadas", - "despesas_liquidadas", - "despesas_pagas", - ], - incremental_strategy="merge", - ) -}} - -with - empenhos_raw as ( - select - emissao_mes::text as emissao_mes, - emissao_dia::text as emissao_dia, - ne_ccor::text as ne_ccor, - regexp_replace(ne_num_processo, '[./-]', '') as ne_num_processo, - ne_info_complementar::text as ne_info_complementar, - ne_ccor_descricao::text as ne_ccor_descricao, - doc_observacao::text as doc_observacao, - natureza_despesa::text as natureza_despesa, - natureza_despesa_descricao::text as natureza_despesa_descricao, - upper(ne_ccor_favorecido::text) as ne_ccor_favorecido, - ne_ccor_favorecido_descricao::text as ne_ccor_favorecido_descricao, - ne_ccor_ano_emissao::integer as ne_ccor_ano_emissao, - ptres::text as ptres, - fonte_recursos_detalhada::text as fonte_recursos_detalhada, - fonte_recursos_detalhada_descricao::text - as fonte_recursos_detalhada_descricao, - {{ parse_financial_value("despesas_empenhadas") }} as despesas_empenhadas, - {{ parse_financial_value("despesas_liquidadas") }} as despesas_liquidadas, - {{ parse_financial_value("despesas_pagas") }} as despesas_pagas, - {{ parse_financial_value("restos_a_pagar_inscritos") }} - as restos_a_pagar_inscritos, - {{ parse_financial_value("restos_a_pagar_pagos") }} as restos_a_pagar_pagos, - (dt_ingest || '-03:00')::timestamptz as dt_ingest - from {{ source("siafi", "empenhos_tesouro") }} - where ne_ccor_ano_emissao like '20%' - ) - -select * -from empenhos_raw diff --git a/dbt/ipea/models/contratos_dbt/bronze/faturas.sql b/dbt/ipea/models/contratos_dbt/bronze/faturas.sql deleted file mode 100755 index 0a8b5f88..00000000 --- a/dbt/ipea/models/contratos_dbt/bronze/faturas.sql +++ /dev/null @@ -1,51 +0,0 @@ -{{ config(materialized="table") }} - -with - faturas_raw as ( - select - id::integer as id, - contrato_id::integer as contrato_id, - tipolistafatura_id::text as tipolistafatura_id, - justificativafatura_id::text as justificativafatura_id, - sfadrao_id::text as sfadrao_id, - numero::text as numero, - emissao::date as emissao, - prazo::date as prazo, - vencimento::date as vencimento, - -- Limpar o formato numérico das colunas que têm problemas - replace(replace(valor::text, '.', ''), ',', '.')::numeric(15, 2) as valor, - replace(replace(juros::text, '.', ''), ',', '.')::numeric(15, 2) as juros, - replace(replace(multa::text, '.', ''), ',', '.')::numeric(15, 2) as multa, - replace(replace(glosa::text, '.', ''), ',', '.')::numeric(15, 2) as glosa, - replace(replace(valorliquido::text, '.', ''), ',', '.')::numeric( - 15, 2 - ) as valorliquido, - processo::text as processo, - protocolo::date as protocolo, - ateste::date as ateste, - repactuacao::text as repactuacao, - infcomplementar::text as infcomplementar, - mesref::integer as mesref, - anoref::integer as anoref, - situacao::text as situacao, - chave_nfe::text as chave_nfe, - dados_referencia::text as dados_referencia, - dados_item_faturado::text as dados_item_faturado, - jsonb_array_elements( - replace(dados_empenho, '''', '"')::jsonb - ) as dados_empenho, - (dt_ingest || '-03:00')::timestamptz as dt_ingest - from {{ source("compras_gov", "faturas") }} - ), - -- Extrai os campos do JSON e transforma em colunas individuais - faturas_dados_empenho as ( - select - f.*, - f.dados_empenho ->> 'id_empenho' as id_empenho, - upper(f.dados_empenho ->> 'numero_empenho') as numero_empenho, - f.dados_empenho ->> 'valor_empenho' as valor_empenho, - f.dados_empenho ->> 'subelemento' as subelemento - from faturas_raw as f - ) -- -select * -from faturas_dados_empenho diff --git a/dbt/ipea/models/contratos_dbt/bronze/schema.yml b/dbt/ipea/models/contratos_dbt/bronze/schema.yml deleted file mode 100644 index 1ef6173e..00000000 --- a/dbt/ipea/models/contratos_dbt/bronze/schema.yml +++ /dev/null @@ -1,480 +0,0 @@ -version: 2 - -models: - - # Contratos DBT - - ## Bronze - - name: contratos - description: > - Tabela com informações sobre contratos, incluindo detalhes como o valor do contrato, a data de início e término, e o status do contrato. - Esta tabela é fundamental para entender a execução e o cumprimento dos contratos firmados. - A tabela é atualizada diariamente e contém dados de contratos firmados pelo IPEA. - A tabela realiza validações e limpezas dos dados extraídos do ComprasGov, incluindo formatação adequada de valores numéricos, - remoção de caracteres especiais em CPF/CNPJ e normalização de datas. - meta: - tags: - - bronze - columns: - - name: id - description: > - Identificador único do contrato, utilizado para referenciar o contrato em outras tabelas e análises. - - name: receita_despesa - description: > - Indica se o contrato é de receita ou despesa. - - name: numero - description: > - Número do contrato no sistema ComprasGov. - - name: fornecedor_tipo - description: > - Tipo do fornecedor (PF, PJ, IDGENERICO para empresas do exterior). - - name: fornecedor_nome - description: > - Nome do fornecedor contratado. - - name: tipo - description: > - Tipo de contrato ( Contrato, Empenho, Termo de Compromisso, etc.). - - name: situacao - description: > - Situação atual do contrato ( Ativo, Inativo). - - name: categoria - description: > - Categoria do contrato ( Informática, Serviços, Mão de Obra, Serviços de Engenharia, etc.). - - name: objeto - description: > - Descrição do objeto contratado. - - name: codigo_modalidade - description: > - Código que identifica a modalidade do contrato. - - name: modalidade - description: > - Modalidade do contrato ( Pregão, Dispensa, Inexigibilidade, etc.). - - name: num_parcelas - description: > - Número de parcelas para pagamento do contrato. - - name: valor_inicial - description: > - Valor inicial do contrato, formatado como numérico. - - name: valor_global - description: > - Valor total do contrato após eventuais aditivos, formatado como numérico. - - name: valor_parcela - description: > - Valor de cada parcela do contrato, formatado como numérico. - - name: valor_acumulado - description: > - Valor acumulado já realizado do contrato, formatado como numérico. - - name: fornecedor_cnpj_cpf_idgener - description: > - CNPJ, CPF ou identificador genérico do fornecedor, com formatação padronizada para remoção de caracteres especiais. - - name: processo - description: > - Número do processo administrativo relacionado ao contrato, formatado para remover caracteres especiais. - - name: data_assinatura - description: > - Data em que o contrato foi assinado, validada e convertida para formato de data padrão. - - name: data_publicacao - description: > - Data de publicação do contrato no Diário Oficial, validada e convertida para formato de data padrão. - - name: vigencia_inicio - description: > - Data de início da vigência do contrato, validada e convertida para formato de data padrão. - - name: vigencia_fim - description: > - Data de término da vigência do contrato, validada e convertida para formato de data padrão. - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) em que os dados foram ingeridos da fonte original para a camada raw. - data_tests: - - row_count_match: - source_table: compras_gov.contratos - target_table: contratos.contratos - - verificacao_tipagem: - nome_tabela: 'contratos.contratos' - nome_coluna: 'num_parcelas' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'contratos.contratos' - nome_coluna: 'valor_inicial' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'contratos.contratos' - nome_coluna: 'valor_global' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'contratos.contratos' - nome_coluna: 'valor_parcela' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'contratos.contratos' - nome_coluna: 'valor_acumulado' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'contratos.contratos' - nome_coluna: 'data_assinatura' - tipo_esperado: 'date' - - verificacao_tipagem: - nome_tabela: 'contratos.contratos' - nome_coluna: 'data_publicacao' - tipo_esperado: 'date' - - verificacao_tipagem: - nome_tabela: 'contratos.contratos' - nome_coluna: 'data_proposta_comercial' - tipo_esperado: 'date' - - verificacao_tipagem: - nome_tabela: 'contratos.contratos' - nome_coluna: 'vigencia_inicio' - tipo_esperado: 'date' - - verificacao_tipagem: - nome_tabela: 'contratos.contratos' - nome_coluna: 'vigencia_fim' - tipo_esperado: 'date' - - - name: cronogramas - description: > - Essa tabela contém informações sobre as despesas mensais programadas para cada contrato. - Os dados são extraídos da tabela cronograma do ComprasGov, com valores formatados adequadamente. - Apresenta o planejamento financeiro do contrato distribuído em parcelas mensais. - meta: - tags: - - bronze - columns: - - name: id - description: > - Identificador único do cronograma. - - name: contrato_id - description: > - Identificador do contrato relacionado ao cronograma. - - name: tipo - description: > - Tipo de cada item do cronograma. - - name: mesref - description: > - Mês de referência do cronograma. - - name: anoref - description: > - Ano de referência do cronograma. - - name: valor - description: > - Valor programado para o mês e ano de referência, formatado como numérico. - - name: vencimento - description: > - Data de vencimento da parcela do cronograma. - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) em que os dados foram ingeridos da fonte original para a camada raw. - data_tests: - - verificacao_tipagem: - nome_tabela: 'contratos.cronogramas' - nome_coluna: 'id' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'contratos.cronogramas' - nome_coluna: 'contrato_id' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'contratos.cronogramas' - nome_coluna: 'mesref' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'contratos.cronogramas' - nome_coluna: 'anoref' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'contratos.cronogramas' - nome_coluna: 'valor' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'contratos.cronogramas' - nome_coluna: 'vencimento' - tipo_esperado: 'date' - - - name: faturas - description: > - Essa tabela contém informações sobre as faturas emitidas mensalmente de cada contrato. - Os dados são extraídos da tabela faturas do ComprasGov com formatação adequada de valores numéricos e datas. - A tabela inclui um processamento adicional para extrair informações dos empenhos a partir do campo JSON dados_empenho. - meta: - tags: - - bronze - columns: - - name: id - description: > - Identificador único da fatura. - - name: contrato_id - description: > - Identificador do contrato relacionado à fatura. - - name: numero - description: > - Número da fatura emitida pelo fornecedor. - - name: emissao - description: > - Data de emissão da fatura pelo fornecedor. - - name: prazo - description: > - Data limite para pagamento da fatura. - - name: vencimento - description: > - Data de vencimento da fatura. - - name: valor - description: > - Valor bruto da fatura, formatado como numérico. - - name: juros - description: > - Valor de juros aplicados à fatura, formatado como numérico. - - name: multa - description: > - Valor de multa aplicada à fatura, formatado como numérico. - - name: glosa - description: > - Valor de glosa aplicada à fatura, formatado como numérico. - - name: valorliquido - description: > - Valor líquido da fatura após subtrações de glosas, multas ou juros, formatado como numérico. - - name: situacao - description: > - Status atual da fatura (Pago ou Pendente). - - name: mesref - description: > - Mês de referência da fatura. - - name: anoref - description: > - Ano de referência da fatura. - - name: id_empenho - description: > - Identificador do empenho extraído do campo JSON dados_empenho. - - name: numero_empenho - description: > - Número do empenho relacionado à fatura, extraído do campo JSON dados_empenho e convertido para maiúsculas. - - name: valor_empenho - description: > - Valor do empenho extraído do campo JSON dados_empenho. - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) em que os dados foram ingeridos da fonte original para a camada raw. - data_tests: - - verificacao_tipagem: - nome_tabela: 'contratos.faturas' - nome_coluna: 'id' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'contratos.faturas' - nome_coluna: 'contrato_id' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'contratos.faturas' - nome_coluna: 'emissao' - tipo_esperado: 'date' - - verificacao_tipagem: - nome_tabela: 'contratos.faturas' - nome_coluna: 'prazo' - tipo_esperado: 'date' - - verificacao_tipagem: - nome_tabela: 'contratos.faturas' - nome_coluna: 'vencimento' - tipo_esperado: 'date' - - verificacao_tipagem: - nome_tabela: 'contratos.faturas' - nome_coluna: 'valor' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'contratos.faturas' - nome_coluna: 'juros' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'contratos.faturas' - nome_coluna: 'multa' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'contratos.faturas' - nome_coluna: 'glosa' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'contratos.faturas' - nome_coluna: 'valorliquido' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'contratos.faturas' - nome_coluna: 'protocolo' - tipo_esperado: 'date' - - verificacao_tipagem: - nome_tabela: 'contratos.faturas' - nome_coluna: 'ateste' - tipo_esperado: 'date' - - verificacao_tipagem: - nome_tabela: 'contratos.faturas' - nome_coluna: 'mesref' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'contratos.faturas' - nome_coluna: 'anoref' - tipo_esperado: 'integer' - - - name: empenhos - description: > - Essa tabela contém informações sobre os empenhos de cada contrato extraídos do ComprasGov. - Os dados são formatados adequadamente para garantir consistência nos tipos numéricos e de data. - Registra os compromissos de pagamento assumidos pela administração para cada contrato. - meta: - tags: - - bronze - columns: - - name: id - description: > - Identificador único do empenho no ComprasGov. - - name: contrato_id - description: > - Identificador do contrato relacionado ao empenho. - - name: nota_empenho - description: > - Número da nota de empenho registrada no sistema. - - name: credor - description: > - Nome ou razão social do credor do empenho. - - name: credor_obj_cnpj_cpf_idgener - description: > - CNPJ, CPF ou identificador genérico do credor do empenho. - - name: empenhado - description: > - Valor total empenhado, formatado como numérico. - - name: aliquidar - description: > - Valor a liquidar do empenho, formatado como numérico. - - name: liquidado - description: > - Valor já liquidado do empenho, formatado como numérico. - - name: pago - description: > - Valor já pago do empenho, formatado como numérico. - - name: rpinscrito - description: > - Valor inscrito em restos a pagar, formatado como numérico. - - name: rpaliquidar - description: > - Valor inscrito em restos a pagar a liquidar, formatado como numérico. - - name: rpliquidado - description: > - Valor inscrito em restos a pagar já liquidado, formatado como numérico. - - name: rppago - description: > - Valor inscrito em restos a pagar já pago, formatado como numérico. - - name: data_emissao - description: > - Data de emissão do empenho, validada e convertida para formato de data padrão. - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) em que os dados foram ingeridos da fonte original para a camada raw. - data_tests: - - row_count_match: - source_table: compras_gov.empenhos - target_table: contratos.empenhos - - verificacao_tipagem: - nome_tabela: 'contratos.empenhos' - nome_coluna: 'empenhado' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'contratos.empenhos' - nome_coluna: 'aliquidar' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'contratos.empenhos' - nome_coluna: 'liquidado' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'contratos.empenhos' - nome_coluna: 'pago' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'contratos.empenhos' - nome_coluna: 'rpinscrito' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'contratos.empenhos' - nome_coluna: 'rpaliquidar' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'contratos.empenhos' - nome_coluna: 'rpliquidado' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'contratos.empenhos' - nome_coluna: 'rppago' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'contratos.empenhos' - nome_coluna: 'data_emissao' - tipo_esperado: 'date' - - - name: empenhos_tesouro - description: > - Essa tabela contém informações sobre movimentação financeira dos empenhos extraídos do SIAFI. - Contém dados de empenhos do Tesouro Nacional com formatação de valores financeiros através da macro parse_financial_value. - Apresenta valores para as diferentes etapas da execução orçamentária (empenho, liquidação, pagamento). - meta: - tags: - - bronze - columns: - - name: emissao_mes - description: > - Mês de emissão do empenho. - - name: emissao_dia - description: > - Data específica de emissão do empenho. - - name: ne_ccor - description: > - Número completo da nota de empenho no SIAFI. - - name: ne_num_processo - description: > - Número do processo relacionado ao empenho, com formatação para remover caracteres especiais. - - name: ne_info_complementar - description: > - Informações complementares sobre o empenho. - - name: ne_ccor_favorecido - description: > - CNPJ ou CPF do favorecido, formatado em caixa alta. - - name: ne_ccor_ano_emissao - description: > - Ano de emissão do empenho, filtrado para incluir apenas empenhos a partir do ano 2000. - - name: despesas_empenhadas - description: > - Valor das despesas empenhadas, formatado como numérico. - - name: despesas_liquidadas - description: > - Valor das despesas liquidadas, formatado como numérico. - - name: despesas_pagas - description: > - Valor das despesas pagas, formatado como numérico. - - name: restos_a_pagar_inscritos - description: > - Valor dos restos a pagar inscritos, formatado como numérico. - - name: restos_a_pagar_pagos - description: > - Valor dos restos a pagar pagos, formatado como numérico. - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) em que os dados foram ingeridos da fonte original para a camada raw. - data_tests: - - verificacao_tipagem: - nome_tabela: 'contratos.empenhos_tesouro' - nome_coluna: 'ne_ccor_ano_emissao' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'contratos.empenhos_tesouro' - nome_coluna: 'despesas_empenhadas' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'contratos.empenhos_tesouro' - nome_coluna: 'despesas_liquidadas' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'contratos.empenhos_tesouro' - nome_coluna: 'despesas_pagas' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'contratos.empenhos_tesouro' - nome_coluna: 'restos_a_pagar_inscritos' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'contratos.empenhos_tesouro' - nome_coluna: 'restos_a_pagar_pagos' - tipo_esperado: 'numeric' diff --git a/dbt/ipea/models/contratos_dbt/gold/contratos_comparativo_mensal.sql b/dbt/ipea/models/contratos_dbt/gold/contratos_comparativo_mensal.sql deleted file mode 100644 index 3c192cd3..00000000 --- a/dbt/ipea/models/contratos_dbt/gold/contratos_comparativo_mensal.sql +++ /dev/null @@ -1,45 +0,0 @@ -with - - siafi_data as ( - select *, mes_lancamento as mes_ref from {{ ref("contratos_estagios") }} - ), - - compras_gov_data as (select * from {{ ref("cronogramas_faturas_mensal") }}), - - partial_result as ( - select - contrato_id, - mes_ref, - c.valor_cronograma as comprasgov_valor_cronograma, - ( - c.valor_faturas_pagas + c.valor_faturas_pendentes - ) as comprasgov_valor_faturas, - c.saldo_contratual_disponivel as comprasgov_saldo_contratual_disponivel, - s.valor_empenhado as siafi_valor_empenhado, - s.valor_liquidado as siafi_valor_liquidado, - s.valor_pago as siafi_valor_pago, - s.restos_a_pagar as siafi_restos_a_pagar, - s.restos_a_pagar_pago as siafi_restos_a_pagar_pago, - c.dt_ingest as dt_ingest - from compras_gov_data as c - full join siafi_data as s using (contrato_id, mes_ref) - - ), - - preenchimento as (select contrato_id, mes_ref from {{ ref("preenchimento_meses") }}) - --- -select - contrato_id, - mes_ref, - comprasgov_valor_cronograma, - comprasgov_valor_faturas, - comprasgov_saldo_contratual_disponivel, - siafi_valor_empenhado, - siafi_valor_liquidado, - siafi_valor_pago, - siafi_restos_a_pagar, - siafi_restos_a_pagar_pago, - dt_ingest -from partial_result -full join preenchimento using (contrato_id, mes_ref) diff --git a/dbt/ipea/models/contratos_dbt/gold/contratos_resumo.sql b/dbt/ipea/models/contratos_dbt/gold/contratos_resumo.sql deleted file mode 100755 index de5e03c0..00000000 --- a/dbt/ipea/models/contratos_dbt/gold/contratos_resumo.sql +++ /dev/null @@ -1,53 +0,0 @@ -with - - valores_pagos_contratos as ( - select contrato_id as id, sum(despesas_pagas) as despesas_pagas, max(dt_ingest) as dt_ingest_vpc - from {{ ref("contratos_empenhos") }} - where contrato_id is not null - group by contrato_id - ), - - contratos_gold as ( - select - *, - case - when vp.despesas_pagas = c.valor_global then 'Sim' else 'Não' - end as pendente_baixa - from {{ ref("contratos") }} as c - left join valores_pagos_contratos as vp using (id) - ) - --- -select - id as contrato_id, - fornecedor_cnpj_cpf_idgener as fornecedor_cnpj_cpf, - numero, - categoria, - modalidade, - tipo, - situacao, - pendente_baixa, - fornecedor_nome, - objeto, - valor_global, - despesas_pagas, - vigencia_inicio, - vigencia_fim, - num_parcelas, - case - when fornecedor_tipo = 'IDGENERICO' - then 'Empresa do Exterior' - else fornecedor_tipo - end as fornecedor_tipo, - concat( - contratante__orgao_origem__unidade_gestora_origem__codigo, - ' - ', - contratante__orgao_origem__unidade_gestora_origem__nome_resumido - ) as "Unidade", - case - when vigencia_fim - vigencia_inicio >= 730 and num_parcelas > 1 - then 'Sim' - else 'Não' - end as continuado, - greatest(dt_ingest, dt_ingest_vpc) as dt_ingest -from contratos_gold diff --git a/dbt/ipea/models/contratos_dbt/gold/contratos_somatorio.sql b/dbt/ipea/models/contratos_dbt/gold/contratos_somatorio.sql deleted file mode 100644 index 523dd547..00000000 --- a/dbt/ipea/models/contratos_dbt/gold/contratos_somatorio.sql +++ /dev/null @@ -1,18 +0,0 @@ -select - contrato_id, - sum(comprasgov_valor_cronograma) as total_cronograma, - sum(comprasgov_valor_faturas) as total_faturas, - sum(comprasgov_saldo_contratual_disponivel) as total_saldo_disponivel, - - -- Indicador de Orçamento a Executar: - sum( - case when comprasgov_valor_faturas = 0 then comprasgov_valor_cronograma else 0 end - ) as orcamento_a_executar, - - sum(siafi_valor_empenhado) as total_empenhado, - sum(siafi_valor_liquidado) as total_liquidado, - sum(siafi_valor_pago) as total_pago, - max(dt_ingest) as dt_ingest - -from {{ ref("contratos_comparativo_mensal") }} -group by contrato_id diff --git a/dbt/ipea/models/contratos_dbt/gold/schema.yml b/dbt/ipea/models/contratos_dbt/gold/schema.yml deleted file mode 100644 index c8ce30b4..00000000 --- a/dbt/ipea/models/contratos_dbt/gold/schema.yml +++ /dev/null @@ -1,148 +0,0 @@ -version: 2 - -models: - - ## Golds - - name: contratos_resumo - description: > - Essa tabela contém um resumo dos contratos, informações contratuais como valor global e valor pago, - e situação atual, como em vigência ou pendente de baixa. - Facilita a análise gerencial dos contratos com indicadores chave como status de pagamento, tipo de fornecedor, - e identificação de contratos continuados (com vigência superior a dois anos e mais de uma parcela). - meta: - tags: - - gold - columns: - - name: contrato_id - description: > - Identificador único do contrato. - - name: fornecedor_cnpj_cpf - description: > - CNPJ ou CPF do fornecedor contratado, com formatação padronizada. - - name: numero - description: > - Número do contrato no sistema ComprasGov. - - name: categoria - description: > - Categoria do contrato ( Informática, Serviços, Mão de Obra). - - name: modalidade - description: > - Modalidade de licitação utilizada na contratação. - - name: tipo - description: > - Tipo de contrato ( Contrato, Empenho, Termo de Compromisso). - - name: situacao - description: > - Situação atual do contrato (Ativo ou Inativo). - - name: pendente_baixa - description: > - Indica se o contrato está pendente de baixa ('Sim' quando o valor pago for igual ao valor global, 'Não' caso contrário). - - name: fornecedor_nome - description: > - Nome ou razão social do fornecedor contratado. - - name: objeto - description: > - Descrição detalhada do objeto contratado. - - name: valor_global - description: > - Valor total do contrato após eventuais aditivos. - - name: despesas_pagas - description: > - Valor total já pago do contrato conforme registros do SIAFI. - - name: vigencia_inicio - description: > - Data de início da vigência do contrato. - - name: vigencia_fim - description: > - Data de término da vigência do contrato. - - name: num_parcelas - description: > - Número de parcelas para pagamento do contrato. - - name: fornecedor_tipo - description: > - Tipo do fornecedor, categorizado como 'Empresa do Exterior' para IDGENERICO. - - name: Unidade - description: > - Unidade gestora responsável pelo contrato, no formato "código - nome_resumido". - - name: continuado - description: > - Indica se o contrato é de prestação continuada ('Sim' quando a vigência for maior que 730 dias e tiver mais de uma parcela). - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) mais recente de ingestão dos dados das tabelas fonte utilizadas neste modelo. - - - name: contratos_comparativo_mensal - description: > - Essa tabela contém um comparativo mensal dos contratos, discriminando - os valores empenhados, liquidados e pagos do SIAFI, - programados e faturados do ComprasGov. - Permite a identificação de inconsistências entre os sistemas e o acompanhamento detalhado - da execução financeira mensal de cada contrato. - meta: - tags: - - gold - columns: - - name: contrato_id - description: > - Identificador único do contrato. - - name: mes_ref - description: > - Mês de referência da informação financeira, preenchido para todos os meses entre o início e fim do contrato. - - name: comprasgov_valor_cronograma - description: > - Valor programado para o mês conforme cronograma registrado no ComprasGov. - - name: comprasgov_valor_faturas - description: > - Soma dos valores das faturas (pagas e pendentes) no mês de referência conforme ComprasGov. - - name: comprasgov_saldo_contratual_disponivel - description: > - Diferença entre o valor programado e o valor faturado no mês, indicando o saldo disponível. - - name: siafi_valor_empenhado - description: > - Valor empenhado no mês de referência conforme registros do SIAFI. - - name: siafi_valor_liquidado - description: > - Valor liquidado no mês de referência conforme registros do SIAFI. - - name: siafi_valor_pago - description: > - Valor pago no mês de referência conforme registros do SIAFI. - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) mais recente de ingestão dos dados das tabelas fonte utilizadas neste modelo. - - - name: contratos_somatorio - description: > - Essa tabela contém somatórios dos valores de cronograma, fatura, empenho, liquidação e pagamento para cada contrato. - Facilita análises agregadas sobre a execução financeira total de cada contrato, com indicadores importantes - como o orçamento pendente de execução. - meta: - tags: - - gold - columns: - - name: contrato_id - description: > - Identificador único do contrato. - - name: total_cronograma - description: > - Soma de todos os valores programados no cronograma do contrato. - - name: total_faturas - description: > - Soma de todos os valores faturados (pagos e pendentes) para o contrato. - - name: total_saldo_disponivel - description: > - Diferença total entre valores programados e faturados, indicando o saldo contratual disponível. - - name: orcamento_a_executar - description: > - Soma dos valores programados em meses onde ainda não houve faturamento, indicando o orçamento pendente de execução. - - name: total_empenhado - description: > - Soma de todos os valores empenhados para o contrato segundo o SIAFI. - - name: total_liquidado - description: > - Soma de todos os valores liquidados para o contrato segundo o SIAFI. - - name: total_pago - description: > - Soma de todos os valores pagos para o contrato segundo o SIAFI. - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) mais recente de ingestão dos dados das tabelas fonte utilizadas neste modelo. diff --git a/dbt/ipea/models/contratos_dbt/silver/contratos_empenhos.sql b/dbt/ipea/models/contratos_dbt/silver/contratos_empenhos.sql deleted file mode 100755 index 4eed67c3..00000000 --- a/dbt/ipea/models/contratos_dbt/silver/contratos_empenhos.sql +++ /dev/null @@ -1,210 +0,0 @@ -with - contratos_com_ne_cnpj_cpf as ( - select distinct contrato_id, ne, cnpj_cpf - from {{ ref("identificadores") }} - where ne is not null - ), - - empenhos_tesouro_transformed as ( - select - *, - case - when ne_ccor is not null then upper(right(ne_ccor, 12)) - end as ne_transformed - from {{ ref("empenhos_tesouro") }} - ), - - -- Primeiro merge: apenas os contratos que tem ne e cnpj_cpf - full_join as ( - select - *, - case - when c.cnpj_cpf is not null and e.ne_ccor_favorecido is not null - then 'both' - when c.cnpj_cpf is not null and e.ne_ccor_favorecido is null - then 'left only' -- nao existe no empenhos_tesouro - when c.cnpj_cpf is null and e.ne_ccor_favorecido is not null - then 'right only' -- existe no empenhos_tesouro mas nao no raw.contratos (ESSA QUE NÓS QUEREMOS) - end as origem - from contratos_com_ne_cnpj_cpf as c - full join - empenhos_tesouro_transformed as e - on c.ne = e.ne_transformed - and c.cnpj_cpf = e.ne_ccor_favorecido - ), - - resultado_1 as ( - select - contrato_id, - coalesce(ne_transformed, ne) as ne_transformed, - ne_ccor, - ne_info_complementar, - ne_num_processo, - ne_ccor_descricao, - doc_observacao, - natureza_despesa, - natureza_despesa_descricao, - ne_ccor_favorecido, - ne_ccor_ano_emissao, - despesas_empenhadas, - despesas_liquidadas, - despesas_pagas, - dt_ingest - from full_join - where origem = 'both' or origem = 'left only' - -- contrato_id nulo significa lacuna no lado esquerdo do RIGHT JOIN, - -- ou contratos em que o join usando ne e cnpj/cpf não foi possível - ), - - -- --------------------------------------------------------------------------------------------------- - empenhos_restantes_1 as ( - select * - from empenhos_tesouro_transformed - where ne_ccor in (select ne_ccor from full_join where origem = 'right only') - ), - - todos_contratos as ( - select distinct contrato_id, processo, cnpj_cpf, info_complementar - from {{ ref("identificadores") }} - ), - - -- Segundo merge: usando processos em que há um único contrato - processos_unicos as ( - select distinct contrato_id, processo as num_processo - from todos_contratos - where - processo in ( - select processo from todos_contratos group by processo having count(*) = 1 - ) - ), - - juncao_processo as ( - select * - from processos_unicos as cpu - right join empenhos_restantes_1 as er on cpu.num_processo = er.ne_num_processo - ), - - resultado_2 as ( - select - contrato_id, - ne_transformed, - ne_ccor, - ne_info_complementar, - ne_num_processo, - ne_ccor_descricao, - doc_observacao, - natureza_despesa, - natureza_despesa_descricao, - ne_ccor_favorecido, - ne_ccor_ano_emissao, - despesas_empenhadas, - despesas_liquidadas, - despesas_pagas, - dt_ingest - from juncao_processo - -- WHERE origem = 'both' - where contrato_id is not null - ), - -- --------------------------------------------------------------------------------------------------- - empenhos_restantes_2 as ( - select * - from empenhos_restantes_1 - where ne_ccor not in (select ne_ccor from resultado_2) - ), - - -- Terceiro merge: usando CNPJs que possuem um único contrato - cnpjs_unicos as ( - select distinct contrato_id, cnpj_cpf - from todos_contratos - where - cnpj_cpf in ( - select cnpj_cpf from todos_contratos group by cnpj_cpf having count(*) = 1 - ) - ), - - juncao_cnpjs as ( - select * - from cnpjs_unicos as cu - right join empenhos_restantes_2 as er on cu.cnpj_cpf = er.ne_ccor_favorecido - ), - - resultado_3 as ( - select - contrato_id, - ne_transformed, - ne_ccor, - ne_info_complementar, - ne_num_processo, - ne_ccor_descricao, - doc_observacao, - natureza_despesa, - natureza_despesa_descricao, - ne_ccor_favorecido, - ne_ccor_ano_emissao, - despesas_empenhadas, - despesas_liquidadas, - despesas_pagas, - dt_ingest - from juncao_cnpjs - where contrato_id is not null - ), - -- --------------------------------------------------------------------------------------------------- - empenhos_restantes_3 as ( - select - *, - -- garantir que ambos os lados estão no mesmo formato - substring(ne_info_complementar from '^([0-9]+) -') as info_complementar - from empenhos_restantes_2 - where ne_ccor not in (select ne_ccor from resultado_3) - ), - - contratos_info_complementar as ( - select distinct contrato_id, info_complementar from todos_contratos - ), - - -- Quarto merge: usando "informação complementar", que é um agregado da unidade - -- gestora + modalidade + numero do contrato ou numero da licitação - juncao_info_complementar as ( - select * - from contratos_info_complementar as c - right join empenhos_restantes_3 as e on c.info_complementar = e.info_complementar - ), - - resultado_4 as ( - select - contrato_id, - ne_transformed, - ne_ccor, - ne_info_complementar, - ne_num_processo, - ne_ccor_descricao, - doc_observacao, - natureza_despesa, - natureza_despesa_descricao, - ne_ccor_favorecido, - ne_ccor_ano_emissao, - despesas_empenhadas, - despesas_liquidadas, - despesas_pagas, - dt_ingest - from juncao_info_complementar - where contrato_id is not null - ), - - -- União de todos os resultados parciais - resultado_final as ( - select * - from resultado_1 - union - select * - from resultado_2 - union - select * - from resultado_3 - union - select * - from resultado_4 - ) - -select * -from resultado_final diff --git a/dbt/ipea/models/contratos_dbt/silver/contratos_estagios.sql b/dbt/ipea/models/contratos_dbt/silver/contratos_estagios.sql deleted file mode 100644 index a833e1ee..00000000 --- a/dbt/ipea/models/contratos_dbt/silver/contratos_estagios.sql +++ /dev/null @@ -1,116 +0,0 @@ -with - - ids_filtrados as ( - select contrato_id, ne, cnpj_cpf, processo, info_complementar - from {{ ref("identificadores") }} - where categoria not in ('Cessão') - ), - - -- Join 1 - id_table_1 as (select distinct contrato_id, ne, cnpj_cpf from ids_filtrados), - - joined_table_1 as ( - select - contrato_id, - cnpj_cpf, - ne, - num_processo, - info_complementar, - mes_lancamento, - valor_empenhado, - valor_liquidado, - valor_pago, - restos_a_pagar, - restos_a_pagar_pago, - dt_ingest - from {{ ref("estagios_mensal") }} - left join id_table_1 using (ne, cnpj_cpf) - ), - - -- Part 2 - empenhos_restantes_1 as (select * from joined_table_1 where contrato_id is null), - - id_table_2 as ( - select distinct contrato_id, cnpj_cpf, processo as num_processo - from ids_filtrados l - where - not exists ( - select distinct contrato_id - from joined_table_1 r - where r.contrato_id = l.contrato_id - ) - ), - - joined_table_2 as ( - select - r.contrato_id, - cnpj_cpf, - ne, - num_processo, - info_complementar, - mes_lancamento, - valor_empenhado, - valor_liquidado, - valor_pago, - restos_a_pagar, - restos_a_pagar_pago, - dt_ingest - from empenhos_restantes_1 l - left join id_table_2 r using (cnpj_cpf, num_processo) - ), - - -- Part 3 - empenhos_restantes_2 as (select * from joined_table_2 where contrato_id is null), - - id_table_3 as ( - select distinct t0.contrato_id, t0.cnpj_cpf, t0.info_complementar - from ids_filtrados t0 - left join id_table_1 t1 on t0.contrato_id = t1.contrato_id - left join id_table_2 t2 on t0.contrato_id = t2.contrato_id - where t1.contrato_id is null or t2.contrato_id is null - - ), - - joined_table_3 as ( - select - r.contrato_id, - cnpj_cpf, - ne, - num_processo, - info_complementar, - mes_lancamento, - valor_empenhado, - valor_liquidado, - valor_pago, - restos_a_pagar, - restos_a_pagar_pago, - dt_ingest - from empenhos_restantes_2 l - left join id_table_3 r using (cnpj_cpf, info_complementar) - ), - - result_table as ( - select * - from joined_table_1 - union - select * - from joined_table_2 - union - select * - from joined_table_3 - ) - --- -select - contrato_id, - mes_lancamento, - sum(valor_empenhado) as valor_empenhado, - sum(valor_liquidado) as valor_liquidado, - sum(valor_pago) as valor_pago, - sum(restos_a_pagar) as restos_a_pagar, - sum(restos_a_pagar_pago) as restos_a_pagar_pago, - max(dt_ingest) as dt_ingest -from result_table -where contrato_id is not null -group by 1, 2 -order by contrato_id, mes_lancamento diff --git a/dbt/ipea/models/contratos_dbt/silver/contratos_faturas.sql b/dbt/ipea/models/contratos_dbt/silver/contratos_faturas.sql deleted file mode 100644 index 60dbc949..00000000 --- a/dbt/ipea/models/contratos_dbt/silver/contratos_faturas.sql +++ /dev/null @@ -1,53 +0,0 @@ -{{ config(materialized="table") }} - -with - contratos as ( - select - id::int as contrato_id, - fornecedor_cnpj_cpf_idgener, - processo as processo_contrato, - numero as numero_contrato, - objeto as objeto_contrato - from {{ ref("contratos") }} - ), - - faturas_base as (select * from {{ ref("faturas") }}) - -select - f.id, - f.contrato_id, - c.numero_contrato, - c.processo_contrato as contrato_processo, - c.fornecedor_cnpj_cpf_idgener, - c.objeto_contrato, - f.tipolistafatura_id, - f.justificativafatura_id, - f.sfadrao_id, - f.numero, - f.emissao, - f.prazo, - f.vencimento, - f.valor, - f.juros, - f.multa, - f.glosa, - f.valorliquido, - f.processo, - f.protocolo, - f.ateste, - f.repactuacao, - f.infcomplementar, - f.mesref, - f.anoref, - f.situacao, - f.chave_nfe, - f.dados_referencia, - f.dados_item_faturado, - f.dados_empenho, - f.id_empenho, - f.numero_empenho, - f.valor_empenho, - f.subelemento, - f.dt_ingest -from faturas_base f -left join contratos c on f.contrato_id = c.contrato_id diff --git a/dbt/ipea/models/contratos_dbt/silver/cronogramas_faturas_mensal.sql b/dbt/ipea/models/contratos_dbt/silver/cronogramas_faturas_mensal.sql deleted file mode 100644 index 9cc2eb1e..00000000 --- a/dbt/ipea/models/contratos_dbt/silver/cronogramas_faturas_mensal.sql +++ /dev/null @@ -1,80 +0,0 @@ -with - - cronograma_agg as ( - select contrato_id, vencimento as mes_ref, sum(valor) as valor_cronograma - from {{ ref("cronogramas") }} - group by 1, 2 - order by contrato_id, vencimento - ), - - faturas_parsed as ( - select - contrato_id::integer as contrato_id, - emissao::date as emissao, - replace(replace(juros::text, '.', ''), ',', '.')::numeric(15, 2) as juros, - replace(replace(multa::text, '.', ''), ',', '.')::numeric(15, 2) as multa, - replace(replace(glosa::text, '.', ''), ',', '.')::numeric(15, 2) as glosa, - replace(replace(valorliquido::text, '.', ''), ',', '.')::numeric( - 15, 2 - ) as valorliquido, - situacao::text as situacao, - dt_ingest - from {{ source("compras_gov", "faturas") }} - ), - - faturas_pago as ( - select - contrato_id, - to_date( - split_part(emissao::text, '-', 1) -- verificar se o mês de emissão é o adequado para ser utilizada - || '-' - || split_part(emissao::text, '-', 2), - 'YYYY-MM' - ) as mes_ref, - sum(juros + multa + glosa + valorliquido) as valor_faturas_pagas, - max(dt_ingest) as dt_ingest_pago - from faturas_parsed - where situacao = 'Pago' - group by 1, 2 - ), - - faturas_pendente as ( - select - contrato_id, - to_date( - split_part(emissao::text, '-', 1) - || '-' - || split_part(emissao::text, '-', 2), - 'YYYY-MM' - ) as mes_ref, - sum(juros + multa + glosa + valorliquido) as valor_faturas_pendentes, - max(dt_ingest) as dt_ingest_pendente - from faturas_parsed - where situacao = 'Pendente' - group by 1, 2 - ), - - joined_table as ( - select * - from cronograma_agg - left join faturas_pago using (contrato_id, mes_ref) - left join faturas_pendente using (contrato_id, mes_ref) - ), - - joined_ajustado as ( - select - contrato_id::text, - mes_ref, - coalesce(valor_cronograma, 0) as valor_cronograma, - coalesce(valor_faturas_pagas, 0) as valor_faturas_pagas, - coalesce(valor_faturas_pendentes, 0) as valor_faturas_pendentes, - coalesce(valor_cronograma, 0) - - coalesce(valor_faturas_pagas, 0) - - coalesce(valor_faturas_pendentes, 0) as saldo_contratual_disponivel, - greatest(dt_ingest_pago, dt_ingest_pendente) AS dt_ingest - from joined_table - order by contrato_id, mes_ref - ) - -select * -from joined_ajustado diff --git a/dbt/ipea/models/contratos_dbt/silver/estagios_mensal.sql b/dbt/ipea/models/contratos_dbt/silver/estagios_mensal.sql deleted file mode 100644 index f990dcd9..00000000 --- a/dbt/ipea/models/contratos_dbt/silver/estagios_mensal.sql +++ /dev/null @@ -1,134 +0,0 @@ -with - - parsed_estagios as ( - select - right(ne_ccor, 12) as ne, - case when emissao_dia like '000/%' then true else false end as eh_rap, - case - when emissao_dia like '000/%' - then '01' - else substring(emissao_dia, '\/(\d{2})\/') - end as mes_lancamento, - right(emissao_mes, 4) as ano_lancamento, - ne_ccor_favorecido as cnpj_cpf, - substring(ne_info_complementar, '(^[0-9]+)') as info_complementar, - ne_num_processo, - despesas_empenhadas as valor_empenhado, - despesas_liquidadas as valor_liquidado, - despesas_pagas as valor_pago, - restos_a_pagar_inscritos as restos_a_pagar, - restos_a_pagar_pagos as restos_a_pagar_pago, - dt_ingest - from {{ ref("empenhos_tesouro") }} - where true and ne_ccor != 'Total' - ), - - grouped_estagios as ( - select - ne, - eh_rap, - ano_lancamento::integer as ano_lancamento, - mes_lancamento, - cnpj_cpf, - max(info_complementar) as info_complementar, - max(ne_num_processo) as num_processo, - sum(valor_empenhado) as valor_empenhado, - sum(valor_liquidado) as valor_liquidado, - sum(valor_pago) as valor_pago, - sum(restos_a_pagar) as restos_a_pagar, - sum(restos_a_pagar_pago) as restos_a_pagar_pago, - max(dt_ingest) as dt_ingest - from parsed_estagios - group by 1, 2, 3, 4, 5 - order by 1, 2 - ), - - processo_fixed as ( - select - ne, - cnpj_cpf, - info_complementar, - eh_rap, - mes_lancamento, - ano_lancamento, - case - when eh_rap - then array[ano_lancamento - 1, ano_lancamento] - else array[ano_lancamento] - end as ano_efetivo, - min(num_processo) over (partition by ne) as num_processo, - valor_empenhado, - valor_liquidado, - valor_pago, - restos_a_pagar, - restos_a_pagar_pago, - dt_ingest - from grouped_estagios - ), - - unnest_rap as ( - select - ne, - cnpj_cpf, - info_complementar, - eh_rap, - mes_lancamento, - ano_lancamento, - unnest(ano_efetivo) as ano_efetivo, - num_processo, - valor_empenhado, - valor_liquidado, - valor_pago, - restos_a_pagar, - restos_a_pagar_pago, - dt_ingest - from processo_fixed - ), - - fix_data as ( - select - ne, - cnpj_cpf, - info_complementar, - eh_rap, - case - when ano_efetivo = ano_lancamento then mes_lancamento else '12' - end as mes_lancamento, - ano_lancamento, - ano_efetivo, - num_processo, - valor_empenhado, - valor_liquidado, - valor_pago, - case - when ano_efetivo = ano_lancamento - then restos_a_pagar - else - restos_a_pagar - end as restos_a_pagar, - restos_a_pagar_pago, - dt_ingest - from unnest_rap - ), - - results as ( - select - ne, - cnpj_cpf, - info_complementar, - num_processo, - to_date( - ano_efetivo || '-' || mes_lancamento || '-01', 'YYYY-MM-DD' - ) as mes_lancamento, - valor_empenhado, - valor_liquidado, - valor_pago, - restos_a_pagar, - restos_a_pagar_pago, - dt_ingest - from fix_data - ) - --- -select * -from results -order by ne, cnpj_cpf, mes_lancamento diff --git a/dbt/ipea/models/contratos_dbt/silver/schema.yml b/dbt/ipea/models/contratos_dbt/silver/schema.yml deleted file mode 100644 index fb496acc..00000000 --- a/dbt/ipea/models/contratos_dbt/silver/schema.yml +++ /dev/null @@ -1,272 +0,0 @@ -version: 2 - -models: - - ## Silver - - name: contratos_empenhos - description: > - Essa tabela combina as informações de movimentação financeira dos empenhos com os ids de contrato do IPEA. - Realiza uma complexa estratégia de join entre os contratos e empenhos do tesouro, tentando várias abordagens - para relacionar os dados do SIAFI com os contratos do ComprasGov usando: - 1) número de empenho e CNPJ/CPF, 2) número de processo, 3) CNPJ/CPF único, e 4) informação complementar. - meta: - tags: - - silver - columns: - - name: contrato_id - description: > - Identificador único do contrato relacionado ao empenho. - - name: ne_transformed - description: > - Número da nota de empenho padronizado para facilitar joins entre diferentes fontes. - - name: ne_ccor - description: > - Número completo da nota de empenho no SIAFI. - - name: ne_info_complementar - description: > - Informações complementares sobre o empenho no SIAFI. - - name: ne_num_processo - description: > - Número do processo administrativo relacionado ao empenho, formatado para remover caracteres especiais. - - name: ne_ccor_descricao - description: > - Descrição da nota de empenho conforme registrado no SIAFI. - - name: doc_observacao - description: > - Observações registradas no documento do empenho. - - name: natureza_despesa - description: > - Código da natureza da despesa do empenho. - - name: natureza_despesa_descricao - description: > - Descrição da natureza da despesa do empenho. - - name: ne_ccor_favorecido - description: > - CNPJ ou CPF do favorecido do empenho. - - name: ne_ccor_ano_emissao - description: > - Ano de emissão do empenho. - - name: despesas_empenhadas - description: > - Valor total das despesas empenhadas para o contrato. - - name: despesas_liquidadas - description: > - Valor total das despesas liquidadas para o contrato. - - name: despesas_pagas - description: > - Valor total das despesas pagas para o contrato. - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) mais recente de ingestão dos dados das tabelas fonte utilizadas neste modelo. - - - name: contratos_estagios - description: > - Essa tabela combina as informações de movimentação financeira dos empenhos com os ids de contrato do IPEA mensalmente. - Utiliza uma estratégia de join em cascata, tentando correlacionar os estágios das despesas do SIAFI com os - contratos do ComprasGov através de várias combinações de chaves, incluindo número de empenho, CNPJ/CPF, número - de processo e informações complementares. - meta: - tags: - - silver - columns: - - name: contrato_id - description: > - Identificador único do contrato relacionado aos estágios. - - name: mes_lancamento - description: > - Mês em que o estágio da despesa foi registrado no SIAFI. - - name: valor_empenhado - description: > - Valor empenhado no mês de referência para o contrato. - - name: valor_liquidado - description: > - Valor liquidado no mês de referência para o contrato. - - name: valor_pago - description: > - Valor pago no mês de referência para o contrato. - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) mais recente de ingestão dos dados das tabelas fonte utilizadas neste modelo. - - - name: estagios_mensal - description: > - Essa tabela discrimina os valores empenhados, liquidados e pagos mensalmente extraídos do SIAFI para cada contrato. - Transforma e agrega os dados da tabela empenhos_tesouro do SIAFI, padronizando formatos e consolidando valores - por número de empenho, mês e CNPJ/CPF. - meta: - tags: - - silver - columns: - - name: ne - description: > - Número da nota de empenho no formato padronizado, extraído das 12 últimas posições do ne_ccor. - - name: mes_lancamento - description: > - Mês de referência do lançamento, convertido para formato de data padrão. - - name: cnpj_cpf - description: > - CNPJ ou CPF do favorecido do empenho. - - name: info_complementar - description: > - Informação complementar extraída do ne_info_complementar. - - name: num_processo - description: > - Número do processo administrativo relacionado ao empenho. - - name: valor_empenhado - description: > - Valor total empenhado no mês e para o empenho específico. - - name: valor_liquidado - description: > - Valor total liquidado no mês e para o empenho específico. - - name: valor_pago - description: > - Valor total pago no mês e para o empenho específico. - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) mais recente de ingestão dos dados das tabelas fonte utilizadas neste modelo. - - - name: contratos_faturas - description: > - Essa tabela integra informações detalhadas de faturas com dados dos contratos relacionados. - Permite uma visão completa de cada fatura no contexto do seu contrato, incluindo dados como número de contrato, - processo, objeto e fornecedor. Facilita a análise financeira das faturas em conjunto com seus respectivos contratos. - meta: - tags: - - silver - columns: - - name: id - description: > - Identificador único da fatura. - - name: contrato_id - description: > - Identificador do contrato relacionado à fatura. - - name: numero_contrato - description: > - Número do contrato no sistema ComprasGov. - - name: contrato_processo - description: > - Número do processo administrativo relacionado ao contrato. - - name: fornecedor_cnpj_cpf_idgener - description: > - CNPJ, CPF ou identificador genérico do fornecedor do contrato. - - name: objeto_contrato - description: > - Descrição do objeto contratado. - - name: tipolistafatura_id - description: > - Identificador do tipo de lista de fatura. - - name: justificativafatura_id - description: > - Identificador da justificativa da fatura, quando aplicável. - - name: sfadrao_id - description: > - Identificador do padrão de sistema financeiro relacionado. - - name: numero - description: > - Número da fatura emitida pelo fornecedor. - - name: emissao - description: > - Data de emissão da fatura. - - name: prazo - description: > - Data limite para pagamento da fatura. - - name: vencimento - description: > - Data de vencimento da fatura. - - name: valor - description: > - Valor bruto da fatura. - - name: juros - description: > - Valor de juros aplicados à fatura. - - name: multa - description: > - Valor de multa aplicada à fatura. - - name: glosa - description: > - Valor de glosa aplicada à fatura. - - name: valorliquido - description: > - Valor líquido da fatura após subtrações de glosas, multas ou juros. - - name: processo - description: > - Número do processo administrativo específico da fatura, quando diferente do processo do contrato. - - name: protocolo - description: > - Data de protocolo da fatura no sistema. - - name: ateste - description: > - Data em que a fatura foi atestada, confirmando a entrega do produto ou serviço. - - name: repactuacao - description: > - Indica se a fatura está relacionada a uma repactuação contratual. - - name: infcomplementar - description: > - Informações complementares sobre a fatura. - - name: mesref - description: > - Mês de referência da fatura. - - name: anoref - description: > - Ano de referência da fatura. - - name: situacao - description: > - Status atual da fatura (Pago ou Pendente). - - name: chave_nfe - description: > - Chave da Nota Fiscal Eletrônica associada à fatura, quando disponível. - - name: dados_referencia - description: > - Dados de referência adicionais da fatura, geralmente em formato JSON. - - name: dados_item_faturado - description: > - Detalhamento dos itens faturados, geralmente em formato JSON. - - name: dados_empenho - description: > - Informações sobre o empenho relacionado à fatura, em formato JSON. - - name: id_empenho - description: > - Identificador do empenho extraído do campo JSON dados_empenho. - - name: numero_empenho - description: > - Número do empenho relacionado à fatura. - - name: valor_empenho - description: > - Valor do empenho relacionado à fatura. - - name: subelemento - description: > - Código do subelemento de despesa relacionado à fatura. - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) mais recente de ingestão dos dados das tabelas fonte utilizadas neste modelo. - - - name: cronogramas_faturas_mensal - description: > - Essa tabela discrimina os valores programados e faturados mensalmente pelo ComprasGov para cada contrato. - Combina dados dos cronogramas com as faturas pagas e pendentes, agrupando por contrato e mês de referência, - e calculando o saldo contratual disponível (diferença entre o valor programado e os valores faturados). - meta: - tags: - - silver - columns: - - name: contrato_id - description: > - Identificador único do contrato. - - name: mes_ref - description: > - Mês de referência dos valores programados e faturados. - - name: valor_cronograma - description: > - Valor total programado para o mês de referência conforme cronograma do contrato. - - name: valor_faturas_pagas - description: > - Valor total de faturas com status "Pago" no mês de referência. - - name: valor_faturas_pendentes - description: > - Valor total de faturas com status "Pendente" no mês de referência. - - name: saldo_contratual_disponivel - description: > - Diferença entre o valor programado no cronograma e a soma dos valores faturados (pagos e pendentes). - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) mais recente de ingestão dos dados das tabelas fonte utilizadas neste modelo. diff --git a/dbt/ipea/models/contratos_dbt/views/identificadores.sql b/dbt/ipea/models/contratos_dbt/views/identificadores.sql deleted file mode 100644 index f0301d2f..00000000 --- a/dbt/ipea/models/contratos_dbt/views/identificadores.sql +++ /dev/null @@ -1,59 +0,0 @@ -with - - ids_from_empenhos as ( - select distinct contrato_id::text as contrato_id, upper(nota_empenho) as ne - from {{ ref("empenhos") }} - ), - - ids_from_faturas as ( - select distinct contrato_id::text as contrato_id, upper(numero_empenho) as ne - from {{ ref("faturas") }} - ), - - ids_table as ( - select * - from ids_from_empenhos e - full join ids_from_faturas f using (contrato_id, ne) - ), - - contratos as ( - select - id::text as contrato_id, - categoria, - case when length(numero) = 12 then numero end as ne, - regexp_replace(processo, '[^0-9]', '', 'g') as processo, - regexp_replace(fornecedor_cnpj_cpf_idgener, '[/.-]', '', 'g') as cnpj_cpf, - case - when codigo_modalidade in ('05', '06') - then - concat( - contratante__orgao__unidade_gestora__codigo, - codigo_modalidade, - replace(numero, '/', '') - ) - when codigo_modalidade = '07' - then - concat( - contratante__orgao__unidade_gestora__codigo, - codigo_modalidade, - replace(licitacao_numero, '/', '') - ) - end as info_complementar - from {{ ref("contratos") }} - ), - - identificadores as ( - select - c.contrato_id, - c.categoria, - c.processo, - c.cnpj_cpf, - c.info_complementar, - coalesce(i.ne, c.ne) as ne - from contratos as c - full join ids_table as i on c.contrato_id = i.contrato_id - ) - --- -select * -from identificadores diff --git a/dbt/ipea/models/contratos_dbt/views/preenchimento_meses.sql b/dbt/ipea/models/contratos_dbt/views/preenchimento_meses.sql deleted file mode 100644 index f1f13297..00000000 --- a/dbt/ipea/models/contratos_dbt/views/preenchimento_meses.sql +++ /dev/null @@ -1,17 +0,0 @@ --- Essa view será usada para preencher todos os gaps temporais --- em tabelas gold com o propósito de eliminar decontinuidades --- nas visualizações em linha -with - - contractos_lista as ( - select contrato_id, min(mes_ref) as min_mes, max(mes_ref) as max_mes - from {{ ref("cronogramas_faturas_mensal") }} - group by contrato_id - ), - - meses_lista as (select distinct mes_ref from {{ ref("cronogramas_faturas_mensal") }}) - --- -select c.contrato_id, m.mes_ref -from contractos_lista c -left join meses_lista m on (c.min_mes <= m.mes_ref) and (c.max_mes >= m.mes_ref) diff --git a/dbt/ipea/models/contratos_dbt/views/schema.yml b/dbt/ipea/models/contratos_dbt/views/schema.yml deleted file mode 100644 index 157ad343..00000000 --- a/dbt/ipea/models/contratos_dbt/views/schema.yml +++ /dev/null @@ -1,30 +0,0 @@ -version: 2 - -models: - - ## View - - name: identificadores - description: > - Essa tabela contém os identificadores dos contratos, empenhos e faturas. - Consolida os números de empenho encontrados em diferentes fontes (contratos, faturas, empenhos) - e padroniza informações como processo e CNPJ/CPF para facilitar joins entre as tabelas. - Também cria um campo info_complementar que combina unidade gestora, modalidade e número de contrato/licitação. - columns: - - name: contrato_id - description: > - Identificador único do contrato. - - name: categoria - description: > - Categoria do contrato ( Informática, Serviços, Mão de Obra). - - name: processo - description: > - Número do processo administrativo do contrato, formatado para remover caracteres não numéricos. - - name: cnpj_cpf - description: > - CNPJ ou CPF do fornecedor, formatado para remover caracteres especiais como barras, pontos e hífens. - - name: info_complementar - description: > - Informação complementar construída a partir da unidade gestora, código de modalidade e número do contrato ou licitação. - - name: ne - description: > - Número da nota de empenho relacionada ao contrato, combinando informações de contratos, empenhos e faturas. diff --git a/dbt/ipea/models/metadata/models_metadata.sql b/dbt/ipea/models/metadata/models_metadata.sql deleted file mode 100644 index f1981994..00000000 --- a/dbt/ipea/models/metadata/models_metadata.sql +++ /dev/null @@ -1,67 +0,0 @@ -{{ - config( - materialized='incremental', - unique_key=['schema_name', 'table_name'], - on_schema_change='sync_all_columns' - ) -}} - -{# - Tabela de Metadados dos Modelos dbt - =================================== - - Esta tabela armazena metadados de todos os modelos executados no dbt. - - Campos principais: - - schema_name: Schema do modelo - - table_name: Nome da tabela/modelo - - dt_transform: Data da última transformação (quando o modelo foi executado) - - run_id: ID único da execução do dbt - - A tabela é atualizada de forma incremental, mantendo apenas o registro - mais recente para cada combinação de schema + table_name. -#} - -WITH dbt_models AS ( - {# - Usando a função graph do dbt para iterar sobre todos os modelos do projeto. - Isso garante que capturamos metadados de todos os modelos definidos. - #} - {% set models_data = [] %} - - {% for node in graph.nodes.values() %} - {% if node.resource_type == 'model' %} - {% do models_data.append({ - 'schema_name': node.schema, - 'table_name': node.name, - 'database_name': node.database, - 'materialization': node.config.materialized, - 'description': node.description | default('') | replace("'", "''") - }) %} - {% endif %} - {% endfor %} - - {% for model in models_data %} - SELECT - '{{ model.schema_name }}' AS schema_name, - '{{ model.table_name }}' AS table_name, - '{{ model.database_name }}' AS database_name, - '{{ model.materialization }}' AS materialization, - '{{ model.description[:500] }}' AS description, - ('{{ run_started_at }}'::TIMESTAMP AT TIME ZONE 'UTC' AT TIME ZONE 'America/Sao_Paulo') AS dt_transform, - '{{ invocation_id }}' AS run_id - {% if not loop.last %} - UNION ALL - {% endif %} - {% endfor %} -) - -SELECT - schema_name, - table_name, - database_name, - materialization, - description, - dt_transform, - run_id -FROM dbt_models diff --git a/dbt/ipea/models/metadata/schema.yml b/dbt/ipea/models/metadata/schema.yml deleted file mode 100644 index e4fce0ab..00000000 --- a/dbt/ipea/models/metadata/schema.yml +++ /dev/null @@ -1,46 +0,0 @@ -# yaml-language-server: $schema=https://raw.githubusercontent.com/dbt-labs/dbt-jsonschema/main/schemas/latest/dbt_yml_files-latest.json - -version: 2 - -models: - - name: models_metadata - description: > - Tabela central de metadados que armazena informações sobre todos os modelos dbt executados. - Cada linha representa um modelo único, identificado pela combinação de schema e table_name. - A tabela é atualizada de forma incremental, mantendo histórico das execuções. - meta: - tags: - - metadata - - governance - columns: - - name: schema_name - description: Nome do schema onde o modelo está localizado. - tests: - - not_null - - - name: table_name - description: Nome da tabela/modelo. - tests: - - not_null - - - name: database_name - description: Nome do banco de dados onde o modelo está materializado. - - - name: materialization - description: Tipo de materialização do modelo (table, view, incremental, etc). - - - name: description - description: Descrição do modelo extraída do schema.yml. - - - name: dt_transform - description: > - Data e hora em que o modelo foi transformado/executado pela última vez. - Corresponde ao momento em que a execução do dbt foi iniciada (run_started_at). - Timezone: America/Sao_Paulo (UTC-3). - tests: - - not_null - - - name: run_id - description: > - Identificador único da execução do dbt (invocation_id). - Permite rastrear qual execução gerou a transformação. diff --git a/dbt/ipea/models/orcamento_dbt/bronze/schema.yml b/dbt/ipea/models/orcamento_dbt/bronze/schema.yml deleted file mode 100644 index c498db75..00000000 --- a/dbt/ipea/models/orcamento_dbt/bronze/schema.yml +++ /dev/null @@ -1,14 +0,0 @@ -version: 2 - -models: - - # Orçamento DBT - - ## Bronze - - name: visao_orcamentaria_total - description: > - Esta tabela contém a visão consolidada da execução orçamentária total, - apresentando informações agregadas sobre os recursos disponíveis, empenhados, liquidados e pagos. - meta: - tags: - - bronze diff --git a/dbt/ipea/models/orcamento_dbt/bronze/visao_orcamentaria_total.sql b/dbt/ipea/models/orcamento_dbt/bronze/visao_orcamentaria_total.sql deleted file mode 100644 index cb60d080..00000000 --- a/dbt/ipea/models/orcamento_dbt/bronze/visao_orcamentaria_total.sql +++ /dev/null @@ -1,47 +0,0 @@ -with - source_data as (select * from {{ source("siafi", "visao_orcamentaria_total") }}), - - typed_data as ( - select - ano_exercicio, - unidade_orcamentaria, - unidade_orcamentaria_desc, - acao_governo, - acao_governo_desc, - programa_governo, - programa_governo_desc, - unidade_plano_orcamentario, - plano_orcamentario_1, - plano_orcamentario_2, - programa_plano_orcamentario, - acao_plano_orcamentario, - plano_orcamentario_6, - plano_orcamentario_desc, - elemento_despesa, - elemento_despesa_desc, - orgao_uge, - orgao_uge_desc, - uge_matriz_filial, - ug_executora, - ug_executora_desc, - - -- Campos financeiros/monetários - {{ parse_financial_value("projeto_inicial_loa") }} as projeto_inicial_loa, - {{ parse_financial_value("dotacao_inicial") }} as dotacao_inicial, - {{ parse_financial_value("dotacao_atualizada") }} as dotacao_atualizada, - {{ parse_financial_value("credito_disponivel") }} as credito_disponivel, - {{ parse_financial_value("despesas_empenhadas") }} as despesas_empenhadas, - {{ parse_financial_value("despesas_a_liquidar") }} as despesas_a_liquidar, - {{ parse_financial_value("despesar_a_pagar") }} as despesar_a_pagar, - {{ parse_financial_value("despesas_pagas") }} as despesas_pagas, - {{ parse_financial_value("restos_a_pagar_inscritos") }} - as restos_a_pagar_inscritos, - {{ parse_financial_value("restos_a_pagar_pagos") }} as restos_a_pagar_pagos, - - (dt_ingest || '-03:00')::timestamptz as dt_ingest - - from source_data - ) - -select * -from typed_data diff --git a/dbt/ipea/models/pessoas_dbt/bronze/afastamento_historico.sql b/dbt/ipea/models/pessoas_dbt/bronze/afastamento_historico.sql deleted file mode 100644 index 0bf04e39..00000000 --- a/dbt/ipea/models/pessoas_dbt/bronze/afastamento_historico.sql +++ /dev/null @@ -1,133 +0,0 @@ -with - afastamento_historico_raw as ( - select - adiantamentosalarioferias, - anoexercicio, - datafim, - datafimaquisicao, - dataini, - datainicioaquisicao, - datainicioferiasinterrompidas, - diasrestantes, - gratificacaonatalina, - numerodaparcela, - parcelacontinuacaointerrupcao, - parcelainterrompida, - qtdedias, - cpf, - coddiplomaafastamento, - codocorrencia, - datapublicacaoafastamento, - descdiplomaafastamento, - descocorrencia, - numerodiplomaafastamento, - dt_ingest - -- grmatricula não está presente - from {{ source("siape", "afastamento_historico") }} - ), - - afastamento_historico_cleaned as ( - -- tive que adicionar um nullif adicional pois nas colunas tinha escrito "NaN" - -- como string, diferentemente das outras tabelas - select - nullif( - nullif(nullif(trim(adiantamentosalarioferias), ''), 'NaN'), '[null]' - ) as adiantamentosalarioferias_clean, - nullif( - nullif(nullif(trim(anoexercicio), ''), 'NaN'), '[null]' - ) as anoexercicio_clean, - nullif(nullif(nullif(trim(datafim), ''), 'NaN'), '[null]') as datafim_clean, - nullif( - nullif(nullif(trim(datafimaquisicao), ''), 'NaN'), '[null]' - ) as datafimaquisicao_clean, - nullif(nullif(nullif(trim(dataini), ''), 'NaN'), '[null]') as dataini_clean, - nullif( - nullif(nullif(trim(datainicioaquisicao), ''), 'NaN'), '[null]' - ) as datainicioaquisicao_clean, - nullif( - nullif(nullif(trim(datainicioferiasinterrompidas), ''), 'NaN'), '[null]' - ) as datainicioferiasinterrompidas_clean, - nullif( - nullif(nullif(trim(diasrestantes), ''), 'NaN'), '[null]' - ) as diasrestantes_clean, - nullif( - nullif(nullif(trim(gratificacaonatalina), ''), 'NaN'), '[null]' - ) as gratificacaonatalina_clean, - nullif( - nullif(nullif(trim(numerodaparcela), ''), 'NaN'), '[null]' - ) as numerodaparcela_clean, - nullif( - nullif(nullif(trim(parcelacontinuacaointerrupcao), ''), 'NaN'), '[null]' - ) as parcelacontinuacaointerrupcao_clean, - nullif( - nullif(nullif(trim(parcelainterrompida), ''), 'NaN'), '[null]' - ) as parcelainterrompida_clean, - nullif(nullif(nullif(trim(qtdedias), ''), 'NaN'), '[null]') as qtdedias_clean, - nullif(nullif(nullif(trim(cpf), ''), 'NaN'), '[null]') as cpf_clean, - nullif( - nullif(nullif(trim(coddiplomaafastamento), ''), 'NaN'), '[null]' - ) as coddiplomaafastamento_clean, - nullif( - nullif(nullif(trim(codocorrencia), ''), 'NaN'), '[null]' - ) as codocorrencia_clean, - nullif( - nullif(nullif(trim(datapublicacaoafastamento), ''), 'NaN'), '[null]' - ) as datapublicacaoafastamento_clean, - nullif( - nullif(nullif(trim(descdiplomaafastamento), ''), 'NaN'), '[null]' - ) as descdiplomaafastamento_clean, - nullif( - nullif(nullif(trim(descocorrencia), ''), 'NaN'), '[null]' - ) as descocorrencia_clean, - nullif( - nullif(nullif(trim(numerodiplomaafastamento), ''), 'NaN'), '[null]' - ) as numerodiplomaafastamento_clean, - dt_ingest - from afastamento_historico_raw - ) - -select - null as gr_matricula, -- placeholder para matrícula, pois aqui na tabela histórica não tem ... - adiantamentosalarioferias_clean as adiantamento_salario_ferias, - anoexercicio_clean as ano_exercicio, - -- mesma logica dos dados_afastamento, garantindo os comprimentos corretos - case - when length(datafim_clean) = 8 then to_date(datafim_clean, 'DDMMYYYY') else null - end as dt_fim, - case - when length(datafimaquisicao_clean) = 8 - then to_date(datafimaquisicao_clean, 'DDMMYYYY') - else null - end as dt_fim_aquisicao, - case - when length(dataini_clean) = 8 then to_date(dataini_clean, 'DDMMYYYY') else null - end as dt_ini, - case - when length(datainicioaquisicao_clean) = 8 - then to_date(datainicioaquisicao_clean, 'DDMMYYYY') - else null - end as dt_inicio_aquisicao, - case - when length(datainicioferiasinterrompidas_clean) = 8 - then to_date(datainicioferiasinterrompidas_clean, 'DDMMYYYY') - else null - end as dt_inicio_ferias_interrompidas, - cast(diasrestantes_clean as int) as dias_restantes, - gratificacaonatalina_clean as gratificacao_natalina, - cast(numerodaparcela_clean as int) as numero_parcela, - parcelacontinuacaointerrupcao_clean as parcela_continuacao_interrupcao, - parcelainterrompida_clean as parcela_interrompida, - cast(qtdedias_clean as int) as qtde_dias, - regexp_replace(cpf_clean, '[^0-9]', '', 'g') as cpf, - coddiplomaafastamento_clean as cod_diploma_afastamento, - codocorrencia_clean as cod_ocorrencia, - case - when length(datapublicacaoafastamento_clean) = 8 - then to_date(datapublicacaoafastamento_clean, 'YYYYMMDD') -- Formato YYYYMMDD - else null - end as dt_publicacao_afastamento, - descdiplomaafastamento_clean as desc_diploma_afastamento, - descocorrencia_clean as desc_ocorrencia, - cast(numerodiplomaafastamento_clean as int) as numero_diploma_afastamento, - (dt_ingest || '-03:00')::timestamptz as dt_ingest -from afastamento_historico_cleaned diff --git a/dbt/ipea/models/pessoas_dbt/bronze/cargos_funcoes.sql b/dbt/ipea/models/pessoas_dbt/bronze/cargos_funcoes.sql deleted file mode 100644 index 21463d1b..00000000 --- a/dbt/ipea/models/pessoas_dbt/bronze/cargos_funcoes.sql +++ /dev/null @@ -1,61 +0,0 @@ -with - fonte as ( - select - codigotipo, - nome, - sigla, - codigocargofuncao, - categoria, - nivel, - regraautoridade, - atonormativo__tipoato, - atonormativo__codigounidade, - atonormativo__numero, - atonormativo__dataassinatura, - atonormativo__datapublicacao, - atonormativo__datavigencia, - atonormativo__ementa, - atonormativo__url, - atonormativo__codigotipo, - atonormativo__siglatipo, - denominacoes__denominacao, - dt_ingest - from {{ source("siorg", "cargos_funcao") }} - ), - - denominacoes_expandidas as ( - select - f.*, - denominacao_elem ->> 'codigo' as denominacao_codigo, - denominacao_elem ->> 'descricao' as denominacao_descricao - from - fonte f, - lateral jsonb_array_elements( - replace( - replace(f.denominacoes__denominacao, '''', '"'), 'None', 'null' - )::jsonb - ) as denominacao_elem - ) - -select - codigotipo, - nome, - sigla, - codigocargofuncao, - categoria, - nivel, - regraautoridade, - atonormativo__tipoato, - atonormativo__codigounidade, - atonormativo__numero, - atonormativo__dataassinatura, - atonormativo__datapublicacao, - atonormativo__datavigencia, - atonormativo__ementa, - atonormativo__url, - atonormativo__codigotipo, - atonormativo__siglatipo, - denominacao_codigo, - denominacao_descricao, - (dt_ingest || '-03:00')::timestamptz as dt_ingest -from denominacoes_expandidas diff --git a/dbt/ipea/models/pessoas_dbt/bronze/dados_afastamento.sql b/dbt/ipea/models/pessoas_dbt/bronze/dados_afastamento.sql deleted file mode 100644 index 66bf946a..00000000 --- a/dbt/ipea/models/pessoas_dbt/bronze/dados_afastamento.sql +++ /dev/null @@ -1,109 +0,0 @@ -with - dados_afastamento_raw as ( - select - adiantamentosalarioferias, - anoexercicio, - datafim, - datafimaquisicao, - dataini, - datainicioaquisicao, - gratificacaonatalina, - numerodaparcela, - parcelacontinuacaointerrupcao, - parcelainterrompida, - qtdedias, - grmatricula, - cpf, - coddiplomaafastamento, - codocorrencia, - datapublicacaoafastamento, - descdiplomaafastamento, - descocorrencia, - numerodiplomaafastamento, - datainicioferiasinterrompidas, - diasrestantes, - dt_ingest - from {{ source("siape", "dados_afastamento") }} - ), - - dados_afastamento_cleaned as ( - select - nullif( - trim(adiantamentosalarioferias), '' - ) as adiantamentosalarioferias_clean, - nullif(trim(anoexercicio), '') as anoexercicio_clean, - nullif(trim(datafim), '') as datafim_clean, - nullif(trim(datafimaquisicao), '') as datafimaquisicao_clean, - nullif(trim(dataini), '') as dataini_clean, - nullif(trim(datainicioaquisicao), '') as datainicioaquisicao_clean, - nullif(trim(gratificacaonatalina), '') as gratificacaonatalina_clean, - nullif(trim(numerodaparcela), '') as numerodaparcela_clean, - nullif( - trim(parcelacontinuacaointerrupcao), '' - ) as parcelacontinuacaointerrupcao_clean, - nullif(trim(parcelainterrompida), '') as parcelainterrompida_clean, - nullif(trim(qtdedias), '') as qtdedias_clean, - nullif(trim(grmatricula), '') as grmatricula_clean, - nullif(trim(cpf), '') as cpf_clean, - nullif(trim(coddiplomaafastamento), '') as coddiplomaafastamento_clean, - nullif(trim(codocorrencia), '') as codocorrencia_clean, - nullif( - trim(datapublicacaoafastamento), '' - ) as datapublicacaoafastamento_clean, - nullif(trim(descdiplomaafastamento), '') as descdiplomaafastamento_clean, - nullif(trim(descocorrencia), '') as descocorrencia_clean, - nullif(trim(numerodiplomaafastamento), '') as numerodiplomaafastamento_clean, - nullif( - trim(datainicioferiasinterrompidas), '' - ) as datainicioferiasinterrompidas_clean, - nullif(trim(diasrestantes), '') as diasrestantes_clean, - dt_ingest - from dados_afastamento_raw - ) - -select - adiantamentosalarioferias_clean as adiantamento_salario_ferias, - anoexercicio_clean as ano_exercicio, - -- adicionei esses checks pois tinham algumas strings de datas retornando "0" e - -- quebrando o to_date ... - case - when length(datafim_clean) = 8 then to_date(datafim_clean, 'DDMMYYYY') else null - end as dt_fim, - case - when length(datafimaquisicao_clean) = 8 - then to_date(datafimaquisicao_clean, 'DDMMYYYY') - else null - end as dt_fim_aquisicao, - case - when length(dataini_clean) = 8 then to_date(dataini_clean, 'DDMMYYYY') else null - end as dt_ini, - case - when length(datainicioaquisicao_clean) = 8 - then to_date(datainicioaquisicao_clean, 'DDMMYYYY') - else null - end as dt_inicio_aquisicao, - gratificacaonatalina_clean as gratificacao_natalina, - cast(numerodaparcela_clean as int) as numero_parcela, - parcelacontinuacaointerrupcao_clean as parcela_continuacao_interrupcao, - parcelainterrompida_clean as parcela_interrompida, - cast(qtdedias_clean as int) as qtde_dias, - grmatricula_clean as gr_matricula, - regexp_replace(cpf_clean, '[^0-9]', '', 'g') as cpf, - coddiplomaafastamento_clean as cod_diploma_afastamento, - codocorrencia_clean as cod_ocorrencia, - case - when length(datapublicacaoafastamento_clean) = 8 - then to_date(datapublicacaoafastamento_clean, 'YYYYMMDD') -- Essa veio diferente, n sei o pq - else null - end as dt_publicacao_afastamento, - descdiplomaafastamento_clean as desc_diploma_afastamento, - descocorrencia_clean as desc_ocorrencia, - cast(numerodiplomaafastamento_clean as int) as numero_diploma_afastamento, - case - when length(datainicioferiasinterrompidas_clean) = 8 - then to_date(datainicioferiasinterrompidas_clean, 'DDMMYYYY') - else null - end as dt_inicio_ferias_interrompidas, - cast(diasrestantes_clean as int) as dias_restantes, - (dt_ingest || '-03:00')::timestamptz as dt_ingest -from dados_afastamento_cleaned diff --git a/dbt/ipea/models/pessoas_dbt/bronze/dados_curriculo.sql b/dbt/ipea/models/pessoas_dbt/bronze/dados_curriculo.sql deleted file mode 100644 index c613711f..00000000 --- a/dbt/ipea/models/pessoas_dbt/bronze/dados_curriculo.sql +++ /dev/null @@ -1,45 +0,0 @@ -with - dados_curriculo_raw as ( - select - cpf, - identificunica, - codigo, - codcurso, - nomecurso, - dataconclusao, - instituicao, - nome, - cargahoraria, - cargo, - datainicio, - nomeorgaoempresa, - datafim, - projeto, - infoadicionais, - tipodesc, - dt_ingest - from {{ source("siape", "dados_curriculo") }} - ) - -select - regexp_replace(nullif(trim(cpf), ''), '[^0-9]', '', 'g') as cpf, - nullif(trim(identificunica), '') as ident_unica, - nullif(trim(codigo), '') as codigo_experiencia, - nullif(trim(codcurso), '') as cod_curso, - nullif(trim(nomecurso), '') as nome_curso, - -- Converte YYYYMM para DATE (1º dia do mês) - to_date(nullif(trim(dataconclusao), '') || '01', 'YYYYMMDD') as dt_mes_conclusao, - nullif(trim(instituicao), '') as nome_instituicao, - nullif(trim(nome), '') as nome_area_experiencia, - nullif(trim(cargahoraria), '') as carga_horaria, -- Mantido como varchar para segurança - nullif(trim(cargo), '') as nome_cargo, - -- Converte YYYYMM para DATE (1º dia do mês) - to_date(nullif(trim(datainicio), '') || '01', 'YYYYMMDD') as dt_mes_inicio, - nullif(trim(nomeorgaoempresa), '') as nome_orgao_empresa, - -- Converte YYYYMM para DATE (1º dia do mês) - to_date(nullif(trim(datafim), '') || '01', 'YYYYMMDD') as dt_mes_fim, - nullif(trim(projeto), '') as descricao_projeto, - nullif(trim(infoadicionais), '') as informacoes_adicionais, - nullif(trim(tipodesc), '') as tipo_descricao, - (dt_ingest || '-03:00')::timestamptz as dt_ingest -from dados_curriculo_raw diff --git a/dbt/ipea/models/pessoas_dbt/bronze/dados_dependentes.sql b/dbt/ipea/models/pessoas_dbt/bronze/dados_dependentes.sql deleted file mode 100644 index d34e7443..00000000 --- a/dbt/ipea/models/pessoas_dbt/bronze/dados_dependentes.sql +++ /dev/null @@ -1,53 +0,0 @@ -with - dados_dependentes_raw as ( - select - codcondicao, - codgrauparentesco, - codorgao, - cpf, - matricula, - nome, - nomecondicao, - nomegrauparentesco, - codbeneficio, - datafim, - datainicio, - nomebeneficio, - dt_ingest - from {{ source("siape", "dados_dependentes") }} - ), - - dados_dependentes_cleaned as ( - select - nullif(trim(codcondicao), 'NaN') as codcondicao, - nullif(trim(codgrauparentesco), 'NaN') as codgrauparentesco, - nullif(trim(codorgao), 'NaN') as codorgao, - nullif(trim(cpf), 'NaN') as cpf, - nullif(trim(matricula), 'NaN') as matricula, - nullif(trim(nome), 'NaN') as nome, - nullif(trim(nomecondicao), 'NaN') as nomecondicao, - nullif(trim(nomegrauparentesco), 'NaN') as nomegrauparentesco, - nullif(trim(codbeneficio), 'NaN') as codbeneficio, - nullif(trim(datafim), 'NaN') as datafim, - nullif(trim(datainicio), 'NaN') as datainicio, - nullif(trim(nomebeneficio), 'NaN') as nomebeneficio, - dt_ingest - from dados_dependentes_raw - ) - -select - nullif(codcondicao, '') as cod_condicao, - nullif(codgrauparentesco, '') as cod_grau_parentesco, - nullif(codorgao, '') as cod_orgao, - regexp_replace(nullif(cpf, ''), '[^0-9]', '', 'g') as cpf, - nullif(matricula, '') as matricula, - nullif(nome, '') as nome_dependente, - nullif(nomecondicao, '') as nome_condicao, - nullif(nomegrauparentesco, '') as nome_grau_parentesco, - nullif(codbeneficio, '') as cod_beneficio, - -- Converte para DATE, tratando '', 'NaN' e '00000000' como NULL - to_date(nullif(nullif(datafim, ''), '00000000'), 'DDMMYYYY') as dt_fim, - to_date(nullif(nullif(datainicio, ''), '00000000'), 'DDMMYYYY') as dt_inicio, - nullif(nomebeneficio, '') as nome_beneficio, - (dt_ingest || '-03:00')::timestamptz as dt_ingest -from dados_dependentes_cleaned diff --git a/dbt/ipea/models/pessoas_dbt/bronze/dados_escolares.sql b/dbt/ipea/models/pessoas_dbt/bronze/dados_escolares.sql deleted file mode 100644 index eb282a35..00000000 --- a/dbt/ipea/models/pessoas_dbt/bronze/dados_escolares.sql +++ /dev/null @@ -1,28 +0,0 @@ -with - dados_escolares_raw as ( - select - codcurso, - nomecurso, - codmatricula, - codorgao, - codtitulacao, - nometitulacao, - codescolaridade, - nomeescolaridade, - cpf, - dt_ingest - from {{ source("siape", "dados_escolares") }} - ) - -select - nullif(trim(codcurso), '') as cod_curso, - nullif(trim(nomecurso), '') as nome_curso, - nullif(trim(codmatricula), '') as cod_matricula, - nullif(trim(codorgao), '') as cod_orgao, - nullif(trim(codtitulacao), '') as cod_titulacao, - nullif(trim(nometitulacao), '') as nome_titulacao, - nullif(trim(codescolaridade), '') as cod_escolaridade, - nullif(trim(nomeescolaridade), '') as nome_escolaridade, - regexp_replace(nullif(trim(cpf), ''), '[^0-9]', '', 'g') as cpf, - (dt_ingest || '-03:00')::timestamptz as dt_ingest -from dados_escolares_raw diff --git a/dbt/ipea/models/pessoas_dbt/bronze/dados_financeiros.sql b/dbt/ipea/models/pessoas_dbt/bronze/dados_financeiros.sql deleted file mode 100644 index b1b6d980..00000000 --- a/dbt/ipea/models/pessoas_dbt/bronze/dados_financeiros.sql +++ /dev/null @@ -1,127 +0,0 @@ -with - dados_financeiros_raw as ( - select - codrubrica, - indicadorrd, - nomerubrica, - numeroseq, - valorrubrica, - dataanomesrubrica, - pzrubrica, - mesanopagamento, - cpf, - indicadormovsupl, - perubrica, - dt_ingest - from {{ source("siape", "dados_financeiros") }} - ), - - dados_financeiros_cleaned as ( - select - nullif(trim(codrubrica), '') as cod_rubrica, - nullif(trim(indicadorrd), '') as indicador_rd, - nullif(trim(nomerubrica), '') as nome_rubrica, - nullif(trim(numeroseq), '') as numero_sequencia, - nullif(trim(valorrubrica), '') as valor_rubrica_str, -- Mantém como string - nullif(trim(dataanomesrubrica), '') as data_anomes_rubrica_str, - nullif(trim(pzrubrica), '') as prazo_rubrica, - nullif(trim(mesanopagamento), '') as mes_ano_pagamento_str, - nullif(trim(cpf), '') as cpf_str, - nullif(trim(indicadormovsupl), '') as indicador_mov_supl, - nullif(trim(perubrica), '') as periodo_rubrica, - dt_ingest - from dados_financeiros_raw - ), - - conversao_mes as ( - select - *, - case - upper(substring(data_anomes_rubrica_str, 1, 3)) - when 'JAN' - then '01' - when 'FEV' - then '02' - when 'MAR' - then '03' - when 'ABR' - then '04' - when 'MAI' - then '05' - when 'JUN' - then '06' - when 'JUL' - then '07' - when 'AGO' - then '08' - when 'SET' - then '09' - when 'OUT' - then '10' - when 'NOV' - then '11' - when 'DEZ' - then '12' - else null - end as mes_num_rubrica, - substring(data_anomes_rubrica_str, 4, 4) as ano_rubrica, - case - upper(substring(mes_ano_pagamento_str, 1, 3)) - when 'JAN' - then '01' - when 'FEV' - then '02' - when 'MAR' - then '03' - when 'ABR' - then '04' - when 'MAI' - then '05' - when 'JUN' - then '06' - when 'JUL' - then '07' - when 'AGO' - then '08' - when 'SET' - then '09' - when 'OUT' - then '10' - when 'NOV' - then '11' - when 'DEZ' - then '12' - else null - end as mes_num_pagamento, - substring(mes_ano_pagamento_str, 4, 4) as ano_pagamento, - max(dt_ingest) over () dt_ingest_max - from dados_financeiros_cleaned - ) - -select - cod_rubrica, - indicador_rd, - nome_rubrica, - numero_sequencia, - -- Limpa (remove '.') e converte (',' para '.') para NUMERIC - cast( - replace( - replace(valor_rubrica_str, '.', ''), -- Remove o separador de milhares '.' - ',', - '.' -- Troca a vírgula decimal ',' por '.' - ) as numeric - ) as valor_rubrica, - -- Converte MONYYYY para DATE (primeiro dia do mês) - to_date( - ano_rubrica || '-' || mes_num_rubrica || '-01', 'YYYY-MM-DD' - ) as data_anomes_rubrica, - prazo_rubrica, - -- Converte MONYYYY para DATE (primeiro dia do mês) - to_date( - ano_pagamento || '-' || mes_num_pagamento || '-01', 'YYYY-MM-DD' - ) as mes_ano_pagamento, - regexp_replace(cpf_str, '[^0-9]', '', 'g') as cpf, - indicador_mov_supl, - periodo_rubrica, - (dt_ingest_max || '-03:00')::timestamptz as dt_ingest -from conversao_mes diff --git a/dbt/ipea/models/pessoas_dbt/bronze/dados_funcionais.sql b/dbt/ipea/models/pessoas_dbt/bronze/dados_funcionais.sql deleted file mode 100644 index 9608fd58..00000000 --- a/dbt/ipea/models/pessoas_dbt/bronze/dados_funcionais.sql +++ /dev/null @@ -1,87 +0,0 @@ -with dados_funcionais_raw as (select * from {{ source("siape", "dados_funcionais") }}) - -select - nullif(trim(codativfun), '') as cod_atividade_funcao, - nullif(trim(codfuncao), '') as cod_funcao, - nullif(trim(codjornada), '') as cod_jornada, - nullif(trim(codocorringressoorgao), '') as cod_ocorr_ingresso_orgao, - nullif(trim(codocorringressoservpublico), '') as cod_ocorr_ingresso_serv_publico, - nullif(trim(codorgao), '') as cod_orgao, - nullif(trim(codpadrao), '') as cod_padrao, - nullif(trim(codsitfuncional), '') as cod_situacao_funcional, - nullif(trim(coduorgexercicio), '') as cod_uorg_exercicio, - nullif(trim(codupag), '') as cod_upag, - nullif(trim(codigoorgaoorigem), '') as cod_orgao_origem, - regexp_replace( - nullif(trim(cpfchefiaimediata), ''), '[^0-9]', '', 'g' - ) as cpf_chefia_imediata, - to_date(nullif(trim(dataexercicionoorgao), ''), 'DDMMYYYY') as dt_exercicio_no_orgao, - to_date(nullif(trim(datafimvalear), ''), 'DDMMYYYY') as dt_fim_vale_ar, - to_date(nullif(trim(dataingressofuncao), ''), 'DDMMYYYY') as dt_ingresso_funcao, - to_date( - nullif(trim(dataocorringressoorgao), ''), 'DDMMYYYY' - ) as dt_ocorr_ingresso_orgao, - to_date( - nullif(trim(dataocorringressoservpublico), ''), 'DDMMYYYY' - ) as dt_ocorr_ingresso_serv_publico, - lower(nullif(trim(emailchefiaimediata), '')) as email_chefia_imediata, - lower(nullif(trim(emailinstitucional), '')) as email_institucional, - lower(nullif(trim(emailservidor), '')) as email_servidor, - nullif(trim(identunica), '') as ident_unica, - nullif(trim(matriculasiape), '') as matricula_siape, - nullif(trim(modalidadepgd), '') as modalidade_pgd, - nullif(trim(nomeativfun), '') as nome_atividade_funcao, - nullif(trim(nomechefeuorg), '') as nome_chefe_uorg, - nullif(trim(nomefuncao), '') as nome_funcao, - nullif(trim(nomejornada), '') as nome_jornada, - nullif(trim(nomeocorringressoorgao), '') as nome_ocorr_ingresso_orgao, - nullif(trim(nomeocorringressoservpublico), '') as nome_ocorr_ingresso_serv_publico, - nullif(trim(nomeorgao), '') as nome_orgao, - nullif(trim(nomeregimejuridico), '') as nome_regime_juridico, - nullif(trim(nomesitfuncional), '') as nome_situacao_funcional, - nullif(trim(nomeuorgexercicio), '') as nome_uorg_exercicio, - nullif(trim(nomeupag), '') as nome_upag, - nullif(trim(participapgd), '') as participa_pgd, - cast(replace(nullif(trim(percentualts), ''), ',', '.') as numeric) - / 100 as percentual_ts, - nullif(trim(siglaorgao), '') as sigla_orgao, - nullif(trim(siglaorgaoorigem), '') as sigla_orgao_origem, - nullif(trim(siglaregimejuridico), '') as sigla_regime_juridico, - nullif(trim(siglauorgexercicio), '') as sigla_uorg_exercicio, - nullif(trim(siglaupag), '') as sigla_upag, - regexp_replace(nullif(trim(cpf), ''), '[^0-9]', '', 'g') as cpf, - nullif(trim(codcargo), '') as cod_cargo, - nullif(trim(codclasse), '') as cod_classe, - nullif(trim(codocorraposentadoria), '') as cod_ocorr_aposentadoria, - to_date(nullif(trim(datainivalear), ''), 'DDMMYYYY') as dt_ini_vale_ar, - to_date( - nullif(trim(dataocorraposentadoria), ''), 'DDMMYYYY' - ) as dt_ocorr_aposentadoria, - nullif(trim(nomecargo), '') as nome_cargo, - nullif(trim(nomeclasse), '') as nome_classe, - nullif(trim(nomeocorraposentadoria), '') as nome_ocorr_aposentadoria, - nullif(trim(siglanivelcargo), '') as sigla_nivel_cargo, - nullif(trim(tipovalear), '') as tipo_vale_ar, - nullif(trim(codocorrisencaoir), '') as cod_ocorr_isencao_ir, - to_date( - nullif(trim(datainiocorrisencaoir), ''), 'DDMMYYYY' - ) as dt_ini_ocorr_isencao_ir, - nullif(trim(nomeocorrisencaoir), '') as nome_ocorr_isencao_ir, - nullif(trim(coduorglotacao), '') as cod_uorg_lotacao, - nullif(trim(nomeuorglotacao), '') as nome_uorg_lotacao, - nullif(trim(siglauorglotacao), '') as sigla_uorg_lotacao, - to_date( - nullif(trim(datafimocorrisencaoir), ''), 'DDMMYYYY' - ) as dt_fim_ocorr_isencao_ir, - nullif(trim(codocorrexclusao), '') as cod_ocorr_exclusao, - to_date(nullif(trim(dataocorrexclusao), ''), 'DDMMYYYY') as dt_ocorr_exclusao, - nullif(trim(nomeocorrexclusao), '') as nome_ocorr_exclusao, - to_date(nullif(trim(datauorglotacao), ''), 'DDMMYYYY') as dt_uorg_lotacao, - nullif(trim(codvaletransporte), '') as cod_vale_transporte, - cast( - replace(nullif(trim(valorvaletransporte), ''), ',', '.') as numeric - ) as valor_vale_transporte, - to_date(nullif(trim(datauorgexercicio), ''), 'DDMMYYYY') as dt_uorg_exercicio, - nullif(trim(pontuacaodesempenho), '') as pontuacao_desempenho, -- Mantido como varchar (Não da pra saber se é "A","B" ou é um número > tudo null) - (dt_ingest || '-03:00')::timestamptz as dt_ingest -from dados_funcionais_raw diff --git a/dbt/ipea/models/pessoas_dbt/bronze/dados_pa.sql b/dbt/ipea/models/pessoas_dbt/bronze/dados_pa.sql deleted file mode 100644 index c0c9e907..00000000 --- a/dbt/ipea/models/pessoas_dbt/bronze/dados_pa.sql +++ /dev/null @@ -1,40 +0,0 @@ -with - dados_pa as ( - select - agenciabeneficiario, - bancobeneficiario, - codorgao, - contabeneficiario, - cpfbeneficiario, - matricula, - nomebeneficiario, - valorultimapensao, - cpf_servidor, - codvinculoservidor, - nomealimentado, - nomevinculoservidor, - dt_ingest - from {{ source("siape", "dados_pa") }} - ) - -select - regexp_replace( - nullif(trim(agenciabeneficiario), ''), '[^0-9]', '', 'g' - ) as agencia_beneficiario, - nullif(trim(bancobeneficiario), '') as banco_beneficiario, - nullif(trim(codorgao), '') as cod_orgao, - upper( - regexp_replace(nullif(trim(contabeneficiario), ''), '[^0-9A-Za-z]', '', 'g') - ) as conta_beneficiario, - regexp_replace( - nullif(trim(cpfbeneficiario), ''), '[^0-9]', '', 'g' - ) as cpf_beneficiario, - nullif(trim(matricula), '') as matricula_servidor, - nullif(trim(nomebeneficiario), '') as nome_beneficiario, - nullif(trim(valorultimapensao), '') as valor_ultima_pensao, - regexp_replace(nullif(trim(cpf_servidor), ''), '[^0-9]', '', 'g') as cpf_servidor, - nullif(trim(codvinculoservidor), '') as cod_vinculo_servidor, - nullif(trim(nomealimentado), '') as nome_alimentado, - nullif(trim(nomevinculoservidor), '') as nome_vinculo_servidor, - (dt_ingest || '-03:00')::timestamptz as dt_ingest -from dados_pa diff --git a/dbt/ipea/models/pessoas_dbt/bronze/dados_pessoais.sql b/dbt/ipea/models/pessoas_dbt/bronze/dados_pessoais.sql deleted file mode 100644 index 3df21476..00000000 --- a/dbt/ipea/models/pessoas_dbt/bronze/dados_pessoais.sql +++ /dev/null @@ -1,52 +0,0 @@ -with - dados_pessoais as ( - select - codcor, - codestadocivil, - codnacionalidade, - codsexo, - datanascimento, - gruposanguineo, - nome, - nomecor, - nomeestadocivil, - nomemae, - nomemunicipnasc, - nomenacionalidade, - nomepai, - nomesexo, - numpispasep, - ufnascimento, - cpf, - coddeffisica, - nomedeffisica, - datachegbrasil, - nomepais, - dt_ingest - from {{ source("siape", "dados_pessoais") }} - ) - -select - nullif(trim(codcor), '') as cod_cor, - nullif(trim(codestadocivil), '') as cod_estado_civil, - nullif(trim(codnacionalidade), '') as cod_nacionalidade, - nullif(trim(codsexo), '') as cod_sexo, - to_date(nullif(trim(datanascimento), ''), 'DDMMYYYY') as dt_nascimento, - nullif(trim(gruposanguineo), '') as grupo_sanguineo, - nullif(trim(nome), '') as nome_pessoa, - nullif(trim(nomecor), '') as nome_cor, - nullif(trim(nomeestadocivil), '') as nome_estado_civil, - nullif(trim(nomemae), '') as nome_mae, - nullif(trim(nomemunicipnasc), '') as nome_municipio_nascimento, - nullif(trim(nomenacionalidade), '') as nome_nacionalidade, - nullif(nullif(trim(nomepai), ''), 'NAO DECLARADO') as nome_pai, - nullif(trim(nomesexo), '') as nome_sexo, - regexp_replace(nullif(trim(numpispasep), ''), '[^0-9]', '', 'g') as num_pispasep, - upper(nullif(trim(ufnascimento), '')) as uf_nascimento, - regexp_replace(nullif(trim(cpf), ''), '[^0-9]', '', 'g') as cpf, - nullif(trim(coddeffisica), '') as cod_deficiencia_fisica, - nullif(trim(nomedeffisica), '') as nome_deficiencia_fisica, - to_date(nullif(trim(datachegbrasil), ''), 'DDMMYYYY') as dt_chegada_brasil, - nullif(trim(nomepais), '') as nome_pais_origem, - (dt_ingest || '-03:00')::timestamptz as dt_ingest -from dados_pessoais diff --git a/dbt/ipea/models/pessoas_dbt/bronze/dados_uorg.sql b/dbt/ipea/models/pessoas_dbt/bronze/dados_uorg.sql deleted file mode 100644 index 49020e90..00000000 --- a/dbt/ipea/models/pessoas_dbt/bronze/dados_uorg.sql +++ /dev/null @@ -1,46 +0,0 @@ -with - dados_uorg as ( - select - bairrouorg, - cepuorg, - codmatricula, - codmunicipiouorg, - codorgao, - codorgaouorg, - emailuorg, - enduorg, - logradourouorg, - nomemunicipiouorg, - nomeuorg, - numtelefoneuorg, - numerouorg, - siglauorg, - ufuorg, - cpf, - complementouorg, - numfaxuorg, - dt_ingest - from {{ source("siape", "dados_uorg") }} - ) - -select - nullif(trim(bairrouorg), '') as bairro_uorg, - regexp_replace(nullif(trim(cepuorg), ''), '[^0-9]', '', 'g') as cep_uorg, - nullif(trim(codmatricula), '') as codigo_matricula, - nullif(trim(codmunicipiouorg), '') as codigo_municipio_uorg, - nullif(trim(codorgao), '') as codigo_orgao, - nullif(trim(codorgaouorg), '') as codigo_orgao_uorg, - lower(nullif(trim(emailuorg), '')) as email_uorg, - nullif(trim(enduorg), '') as tipo_endereco_uorg, - nullif(trim(logradourouorg), '') as logradouro_uorg, - nullif(trim(nomemunicipiouorg), '') as nome_municipio_uorg, - nullif(trim(nomeuorg), '') as nome_uorg, - regexp_replace(nullif(trim(numtelefoneuorg), ''), '[^0-9]', '', 'g') as telefone_uorg, - nullif(trim(numerouorg), '') as numero_endereco_uorg, - nullif(trim(siglauorg), '') as sigla_uorg, - upper(nullif(trim(ufuorg), '')) as uf_uorg, - regexp_replace(nullif(trim(cpf), ''), '[^0-9]', '', 'g') as cpf, - nullif(nullif(trim(complementouorg), ''), '---') as complemento_endereco_uorg, - regexp_replace(nullif(trim(numfaxuorg), ''), '[^0-9]', '', 'g') as fax_uorg, - (dt_ingest || '-03:00')::timestamptz as dt_ingest -from dados_uorg diff --git a/dbt/ipea/models/pessoas_dbt/bronze/estrutura_organizacional_cargos.sql b/dbt/ipea/models/pessoas_dbt/bronze/estrutura_organizacional_cargos.sql deleted file mode 100644 index d44b51dd..00000000 --- a/dbt/ipea/models/pessoas_dbt/bronze/estrutura_organizacional_cargos.sql +++ /dev/null @@ -1,78 +0,0 @@ -with - fonte as ( - select - codigounidade, - nomeunidade, - siglaunidade, - municipio, - uf, - cargos, - ordem_grandeza, - dt_ingest - from {{ source("siorg", "estrutura_organizacional_cargos") }} - ), - - cargos_expandidos as ( - select - f.codigounidade, - f.nomeunidade, - f.siglaunidade, - f.municipio, - f.uf, - f.ordem_grandeza, - f.dt_ingest, - cargo_elem - from - fonte f, - lateral jsonb_array_elements( - replace(replace(f.cargos, '''', '"'), 'None', 'null')::jsonb - ) as cargo_elem - ), - - instancias_expandidas as ( - select - ce.codigounidade, - ce.nomeunidade, - ce.siglaunidade, - ce.municipio, - ce.uf, - ce.ordem_grandeza, - ce.dt_ingest, - cargo_elem ->> 'denominacao' as denominacao, - cargo_elem ->> 'funcao' as funcao, - instancia_elem ->> 'codigoInstancia' as codigo_instancia, - instancia_elem ->> 'nomeTitular' as nome_titular, - instancia_elem ->> 'cpfTitular' as cpf_titular - from - cargos_expandidos ce, - lateral jsonb_array_elements(cargo_elem -> 'instancias') as instancia_elem - ), - - instancias_filtradas as ( - select * - from - ( - select - *, - row_number() over ( - partition by codigo_instancia order by ordem_grandeza desc - ) as rn - from instancias_expandidas - ) t - where rn = 1 - ) - -select - codigounidade, - nomeunidade, - siglaunidade, - municipio, - uf, - denominacao, - funcao, - codigo_instancia, - nome_titular, - cpf_titular, - ordem_grandeza, - (dt_ingest || '-03:00')::timestamptz as dt_ingest -from instancias_filtradas diff --git a/dbt/ipea/models/pessoas_dbt/bronze/lista_servidores.sql b/dbt/ipea/models/pessoas_dbt/bronze/lista_servidores.sql deleted file mode 100644 index 9ca75c25..00000000 --- a/dbt/ipea/models/pessoas_dbt/bronze/lista_servidores.sql +++ /dev/null @@ -1,8 +0,0 @@ -with - lista_servidores as ( - select cpf, dataultimatransacao as dt_ultima_transacao, coduorg as cod_uorg, (dt_ingest || '-03:00')::timestamptz as dt_ingest - from {{ source("siape", "lista_servidores") }} - ) - -select * -from lista_servidores diff --git a/dbt/ipea/models/pessoas_dbt/bronze/lista_uorgs.sql b/dbt/ipea/models/pessoas_dbt/bronze/lista_uorgs.sql deleted file mode 100644 index 94954e79..00000000 --- a/dbt/ipea/models/pessoas_dbt/bronze/lista_uorgs.sql +++ /dev/null @@ -1,8 +0,0 @@ -with - lista_uorgs as ( - select cast(codigo as int) as codigo, dt_ultima_transacao, nome, (dt_ingest || '-03:00')::timestamptz as dt_ingest - from {{ source("siape", "lista_uorgs") }} - ) - -select * -from lista_uorgs diff --git a/dbt/ipea/models/pessoas_dbt/bronze/schema.yml b/dbt/ipea/models/pessoas_dbt/bronze/schema.yml deleted file mode 100644 index c3b66dfc..00000000 --- a/dbt/ipea/models/pessoas_dbt/bronze/schema.yml +++ /dev/null @@ -1,906 +0,0 @@ -version: 2 - -models: - - # Pessoas DBT - - ## Bronze - - name: afastamento_historico - description: > - Tabela bronze que armazena o histórico de afastamentos dos servidores. - Contém informações detalhadas sobre cada período de afastamento, incluindo datas, tipo, e amparo legal. - Os dados são limpos e padronizados a partir da fonte original. - meta: - tags: - - bronze - columns: - - name: adiantamento_salario_ferias - description: "Indica se houve adiantamento de salário durante as férias." - - name: ano_exercicio - description: "Ano de exercício a que o afastamento se refere." - - name: dt_fim - description: "Data de término do afastamento." - - name: dt_fim_aquisicao - description: "Data final do período aquisitivo de férias." - - name: dt_ini - description: "Data de início do afastamento." - - name: dt_inicio_aquisicao - description: "Data inicial do período aquisitivo de férias." - - name: dt_inicio_ferias_interrompidas - description: "Data de início de férias que foram interrompidas." - - name: dias_restantes - description: "Dias restantes de afastamento." - - name: gratificacao_natalina - description: "Indica se o afastamento está relacionado à gratificação natalina." - - name: numero_parcela - description: "Número da parcela do afastamento." - - name: parcela_continuacao_interrupcao - description: "Indica se a parcela é uma continuação ou interrupção." - - name: parcelainterrompida - description: "Indica se a parcela foi interrompida." - - name: qtde_dias - description: "Quantidade de dias do afastamento." - - name: cpf - description: "CPF do servidor." - - name: cod_diploma_afastamento - description: "Código do diploma legal do afastamento." - - name: cod_ocorrencia - description: "Código da ocorrência do afastamento." - - name: dt_publicacao_afastamento - description: "Data de publicação do afastamento." - - name: desc_diploma_afastamento - description: "Descrição do diploma legal do afastamento." - - name: desc_ocorrencia - description: "Descrição da ocorrência do afastamento." - - name: numero_diploma_afastamento - description: "Número do diploma legal do afastamento." - - name: dt_ingest - description: "Data e hora (UTC-3 Brasília) em que os dados foram ingeridos da fonte original para a camada raw." - - - - name: cargos_funcoes - description: > - Tabela bronze que representa as funções e cargos extraídos do sistema SIORG. - Ela contém informações sobre o código e nome do cargo/função, nível hierárquico, - categoria funcional, regras de autoridade, além de dados normativos (ato normativo) - e as diversas denominações associadas a cada cargo/função. - Os dados são expandidos a partir de arrays JSON para facilitar a análise. - meta: - tags: - - bronze - columns: - - name: codigotipo - description: "Código que representa o tipo do cargo ou função." - - - name: nome - description: "Nome completo do cargo ou função." - - - name: sigla - description: "Sigla identificadora do cargo ou função." - - - name: codigocargofuncao - description: "Código único que identifica o cargo ou função." - - - name: categoria - description: "Categoria funcional do cargo, como direção, assessoramento, etc." - - - name: nivel - description: "Nível hierárquico do cargo ou função." - - - name: atonormativo__tipoato - description: "Tipo do ato normativo que criou ou regulamenta o cargo/função." - - - name: atonormativo__codigounidade - description: "Código da unidade responsável pelo ato normativo." - - - name: atonormativo__numero - description: "Número do ato normativo relacionado ao cargo ou função." - - - name: atonormativo__dataassinatura - description: "Data em que o ato normativo foi assinado." - - - name: atonormativo__datapublicacao - description: "Data de publicação do ato normativo no diário oficial." - - - name: atonormativo__datavigencia - description: "Data em que o ato normativo passou a vigorar." - - - name: atonormativo__ementa - description: "Ementa ou resumo descritivo do ato normativo." - - - name: atonormativo__url - description: "URL de acesso ao conteúdo completo do ato normativo." - - - name: atonormativo__codigotipo - description: "Código que representa o tipo de ato normativo." - - - name: atonormativo__siglatipo - description: "Sigla que representa o tipo de ato normativo." - - - name: denominacao_codigo - description: "Código individual da denominação expandida a partir do array JSON." - - - name: denominacao_descricao - description: "Descrição da denominação expandida para o cargo/função." - - - name: dt_ingest - description: "Data e hora (UTC-3 Brasília) em que os dados foram ingeridos da fonte original para a camada raw." - - - - name: dados_afastamento - description: > - Tabela bronze com dados atuais de afastamentos dos servidores. - meta: - tags: - - bronze - columns: - - name: adiantamento_salario_ferias - description: "Indica se houve adiantamento de salário durante as férias." - - name: ano_exercicio - description: "Ano de exercício a que o afastamento se refere." - - name: cod_diploma_afastamento - description: "Código do diploma legal do afastamento." - - name: cod_ocorrencia - description: "Código da ocorrência do afastamento." - - name: desc_diploma_afastamento - description: "Descrição do diploma legal do afastamento." - - name: desc_ocorrencia - description: "Descrição da ocorrência do afastamento." - - name: dt_fim - description: "Data de término do afastamento." - - name: dt_ini - description: "Data de início do afastamento." - - name: dt_inicio_aquisicao - description: "Data inicial do período aquisitivo de férias." - - name: dt_publicacao_afastamento - description: "Data de publicação do afastamento." - - name: dias_restantes - description: "Dias restantes de afastamento." - - name: gratificacao_natalina - description: "Indica se o afastamento está relacionado à gratificação natalina." - - name: gr_matricula - description: "Matrícula GR." - - name: numero_diploma_afastamento - description: "Número do diploma legal do afastamento." - - name: numero_parcela - description: "Número da parcela do afastamento." - - name: parcela_continuacao_interrupcao - description: "Indica se a parcela é uma continuação ou interrupção." - - name: qtde_dias - description: "Quantidade de dias do afastamento." - - name: cpf - description: "CPF do servidor." - - name: dt_fim_aquisicao - description: "Data final do período aquisitivo de férias." - - name: dt_ingest - description: "Data e hora (UTC-3 Brasília) em que os dados foram ingeridos da fonte original para a camada raw." - - - - - name: dados_curriculo - description: > - Tabela bronze que representa dados curriculares e experiências profissionais dos servidores públicos. - Inclui informações sobre cursos realizados, instituições de ensino, tempo de experiência, projetos desenvolvidos e vínculos com órgãos ou empresas. - As datas foram padronizadas para o primeiro dia do mês (`dt_mes_`) e os dados textuais foram limpos de caracteres inválidos. - meta: - tags: - - bronze - columns: - - name: cpf - description: "CPF do servidor, formatado apenas com números." - - - name: ident_unica - description: "Identificador único do servidor no sistema, usado para correlacionar registros." - - - name: codigo_experiencia - description: "Código associado ao tipo de experiência do servidor ( 1 para formação, 2 para experiência profissional)." - - - name: cod_curso - description: "Código do curso realizado, se disponível." - - - name: nome_curso - description: "Nome do curso de formação acadêmica ou técnica. Exemplo: 'Ciências Contábeis', 'Administração'." - - - name: dt_mes_conclusao - description: "Data de conclusão do curso, normalizada para o primeiro dia do mês. Exemplo: '1991-12-01'." - - - name: nome_instituicao - description: "Nome da instituição onde o curso foi realizado. Exemplo: 'UDF', 'Universidade Católica de Brasília'." - - - name: nome_area_experiencia - description: > - Grau ou situação da experiência/capacitação. Pode indicar o nível ou status como: - 'Concluído', 'Intermediário', 'Básico', 'Curso', 'Avançado'." - - - name: carga_horaria - description: "Carga horária do curso, se disponível. Armazenado como texto." - - - name: nome_cargo - description: "Nome do cargo ou função exercida durante a experiência profissional." - - - name: dt_mes_inicio - description: "Data de início da experiência profissional, no formato 'YYYY-MM-01'." - - - name: nome_orgao_empresa - description: "Nome da organização, empresa ou órgão público em que a experiência foi realizada." - - - name: dt_mes_fim - description: "Data de término da experiência profissional, normalizada para o primeiro dia do mês." - - - name: descricao_projeto - description: "Descrição de projetos relevantes associados à experiência." - - - name: informacoes_adicionais - description: "Informações complementares que detalham a experiência ou formação." - - - name: tipo_descricao - description: "Tipo da descrição curricular. Pode indicar se o registro refere-se a curso, experiência, projeto etc." - - - name: dt_ingest - description: "Data e hora (UTC-3 Brasília) em que os dados foram ingeridos da fonte original para a camada raw." - - - - name: dados_dependentes - description: > - Tabela bronze que contém informações sobre os dependentes dos servidores públicos. - Inclui grau de parentesco, condições de dependência, benefícios associados e o período em que a dependência esteve ativa. - Os dados foram tratados para remover valores inválidos como 'NaN' e '00000000', e datas foram convertidas para o formato `DATE`. - meta: - tags: - - bronze - columns: - - name: cod_condicao - description: > - Código que representa a condição da dependência ( dependente econômico, legal, etc.). - Usado para classificar o tipo de vínculo do dependente com o servidor. - - - name: cod_grau_parentesco - description: > - Código que indica o grau de parentesco do dependente com o servidor ( filho, cônjuge, pai, etc.). - - - name: cod_orgao - description: "Código do órgão ao qual o servidor está vinculado." - - - name: cpf - description: "CPF do servidor titular da matrícula, contendo apenas números." - - - name: matricula - description: "Número da matrícula funcional do servidor ao qual o dependente está associado." - - - name: nome_dependente - description: "Nome completo do dependente." - - - name: nome_condicao - description: > - Descrição da condição do dependente ( 'Dependente para IR', 'Dependente para Plano de Saúde'). - - - name: nome_grau_parentesco - description: > - Descrição textual do grau de parentesco entre o servidor e o dependente ( 'Filho', 'Cônjuge'). - - - name: cod_beneficio - description: "Código que representa o tipo de benefício relacionado ao dependente, se houver." - - - name: dt_fim - description: > - Data de término da condição de dependência, no formato 'DDMMYYYY', convertida para DATE. - Pode ser nula se a dependência ainda estiver ativa. - - - name: dt_inicio - description: > - Data de início da condição de dependência, no formato 'DDMMYYYY', convertida para DATE. - - - name: nome_beneficio - description: > - Nome do benefício associado ao dependente ( auxílio-saúde, plano de assistência etc.). - - - name: dt_ingest - description: "Data e hora (UTC-3 Brasília) em que os dados foram ingeridos da fonte original para a camada raw." - - - - name: dados_escolares - description: > - Tabela bronze que armazena dados sobre a formação educacional dos servidores públicos. - Inclui informações sobre escolaridade, titulação e cursos associados às matrículas funcionais. - Os dados foram limpos para remover valores vazios e o CPF foi padronizado contendo apenas dígitos. - meta: - tags: - - bronze - columns: - - name: cod_curso - description: "Código identificador do curso realizado pelo servidor." - - - name: nome_curso - description: "Nome do curso relacionado à formação do servidor." - - - name: cod_matricula - description: "Código da matrícula funcional do servidor, vinculado ao curso." - - - name: cod_orgao - description: "Código do órgão público ao qual o servidor está vinculado." - - - name: cod_titulacao - description: "Código que representa a titulação do servidor ( especialização, mestrado, doutorado)." - - - name: nome_titulacao - description: "Descrição textual da titulação ( 'Mestrado', 'Doutorado')." - - - name: cod_escolaridade - description: "Código do nível de escolaridade ( ensino médio, superior, técnico)." - - - name: nome_escolaridade - description: "Descrição do nível de escolaridade do servidor." - - - name: cpf - description: "CPF do servidor, contendo apenas números, utilizado para identificação única." - - - name: dt_ingest - description: "Data e hora (UTC-3 Brasília) em que os dados foram ingeridos da fonte original para a camada raw." - - - - - name: dados_financeiros - description: > - Tabela bronze que armazena dados financeiros associados a servidores públicos. - Contém informações detalhadas sobre rubricas (proventos e descontos), valores pagos, - períodos de referência e data de pagamento. Os dados passam por limpeza e transformação - de formatos monetários e temporais para garantir consistência e padronização. - meta: - tags: - - bronze - columns: - - name: cod_rubrica - description: "Código da rubrica financeira (provento ou desconto) referente ao pagamento do servidor." - - - name: indicador_rd - description: "Indicador que diferencia se a rubrica é de receita (R) ou despesa (D)." - - - name: nome_rubrica - description: "Nome descritivo da rubrica, como 'Salário Base', 'Auxílio Alimentação', etc." - - - name: numero_sequencia - description: "Número sequencial que identifica a ordem da rubrica na folha de pagamento." - - - name: valor_rubrica - description: > - Valor monetário da rubrica, convertido de string para tipo numérico. - Foi realizada limpeza dos pontos e substituição da vírgula decimal por ponto. - - - name: data_anomes_rubrica - description: > - Data correspondente ao mês e ano de referência da rubrica, convertida do formato textual ( 'JAN2020') para uma data no formato YYYY-MM-DD - com o dia fixado em 01. - - - name: prazo_rubrica - description: "Informação de prazo da rubrica (campo opcional e com dados variados, pode indicar vencimento ou parcelamento)." - - - name: mes_ano_pagamento - description: > - Data correspondente ao mês e ano de efetivação do pagamento, convertida do formato textual ( 'JAN2020') para data com o dia fixado em 01. - - - name: cpf - description: > - CPF do servidor, padronizado contendo apenas dígitos. Utilizado para vinculação com outras informações do servidor. - - - name: indicador_mov_supl - description: > - Indicador que mostra se a movimentação financeira se refere a um pagamento suplementar ou retroativo (campo técnico da folha). - - - name: periodo_rubrica - description: > - Período a que se refere a rubrica, podendo representar um agrupamento ou classificação contábil adicional." - - - name: dt_ingest - description: "Data e hora (UTC-3 Brasília) em que os dados foram ingeridos da fonte original para a camada raw." - - - - name: dados_funcionais - description: > - Tabela bronze que armazena os dados funcionais dos servidores, contendo informações - sobre cargos, funções, regimes jurídicos, ocorrências de ingresso e aposentadoria, e dados - de unidades organizacionais (lotação e exercício). As datas são padronizadas, os CPFs higienizados - e os valores tratados para garantir integridade e legibilidade dos dados. - meta: - tags: - - bronze - columns: - - name: cod_atividade_funcao - description: "Código da atividade ou função exercida pelo servidor." - - - name: cod_funcao - description: "Código identificador da função do servidor." - - - name: cod_jornada - description: "Código da jornada de trabalho do servidor." - - - name: cod_ocorr_ingresso_orgao - description: "Código da ocorrência referente ao ingresso no órgão." - - - name: cod_ocorr_ingresso_serv_publico - description: "Código da ocorrência de ingresso no serviço público federal." - - - name: cod_orgao - description: "Código do órgão atual de lotação ou exercício do servidor." - - - name: cod_padrao - description: "Código do padrão do cargo ocupado." - - - name: cod_situacao_funcional - description: "Código representando a situação funcional atual do servidor (ativo, afastado, etc.)." - - - name: cod_uorg_exercicio - description: "Código da unidade organizacional onde o servidor exerce suas atividades." - - - name: cod_upag - description: "Código da Unidade Pagadora responsável pelo pagamento ao servidor." - - - name: cod_orgao_origem - description: "Código do órgão de origem, em caso de movimentação funcional." - - - name: cpf_chefia_imediata - description: "CPF da chefia imediata, higienizado para conter apenas dígitos." - - - name: dt_exercicio_no_orgao - description: "Data em que o servidor iniciou o exercício no órgão atual." - - - name: dt_fim_vale_ar - description: "Data final da vigência do vale de auxílio-refeição." - - - name: dt_ingresso_funcao - description: "Data de ingresso na função atual." - - - name: dt_ocorr_ingresso_orgao - description: "Data da ocorrência de ingresso no órgão atual." - - - name: dt_ocorr_ingresso_serv_publico - description: "Data da ocorrência de ingresso no serviço público." - - - name: email_chefia_imediata - description: "E-mail institucional da chefia imediata, padronizado em minúsculo." - - - name: email_institucional - description: "E-mail institucional do servidor, padronizado em minúsculo." - - - name: email_servidor - description: "E-mail pessoal do servidor, padronizado em minúsculo." - - - name: ident_unica - description: "Identificação única do servidor no sistema." - - - name: matricula_siape - description: "Matrícula do servidor no sistema SIAPE." - - - name: modalidade_pgd - description: "Modalidade de participação no Programa de Gestão e Desempenho (PGD)." - - - name: nome_atividade_funcao - description: "Descrição textual da atividade ou função exercida." - - - name: nome_chefe_uorg - description: "Nome da chefia imediata da unidade organizacional." - - - name: nome_funcao - description: "Nome da função ocupada." - - - name: nome_jornada - description: "Descrição da jornada de trabalho." - - - name: nome_ocorr_ingresso_orgao - description: "Descrição da ocorrência de ingresso no órgão." - - - name: nome_ocorr_ingresso_serv_publico - description: "Descrição da ocorrência de ingresso no serviço público." - - - name: nome_orgao - description: "Nome do órgão onde o servidor está vinculado." - - - name: nome_regime_juridico - description: "Nome do regime jurídico do servidor ( Estatutário, CLT)." - - - name: nome_situacao_funcional - description: "Descrição da situação funcional do servidor." - - - name: nome_uorg_exercicio - description: "Nome da unidade organizacional de exercício." - - - name: nome_upag - description: "Nome da unidade pagadora responsável pelo servidor." - - - name: participa_pgd - description: "Indica se o servidor participa do Programa de Gestão e Desempenho." - - - name: percentual_ts - description: "Percentual de tempo de trabalho remoto (teletrabalho), convertido para valor numérico ( 0.75 representa 75%)." - - - name: sigla_orgao - description: "Sigla do órgão atual." - - - name: sigla_orgao_origem - description: "Sigla do órgão de origem." - - - name: sigla_regime_juridico - description: "Sigla do regime jurídico do servidor." - - - name: sigla_uorg_exercicio - description: "Sigla da unidade de exercício." - - - name: sigla_upag - description: "Sigla da unidade pagadora." - - - name: cpf - description: "CPF do servidor, com apenas dígitos." - - - name: cod_cargo - description: "Código do cargo efetivo ocupado pelo servidor." - - - name: cod_classe - description: "Código da classe funcional do cargo." - - - name: cod_ocorr_aposentadoria - description: "Código da ocorrência de aposentadoria." - - - name: dt_ini_vale_ar - description: "Data de início do benefício de auxílio-refeição." - - - name: dt_ocorr_aposentadoria - description: "Data da ocorrência de aposentadoria." - - - name: nome_cargo - description: "Nome do cargo efetivo." - - - name: nome_classe - description: "Nome da classe funcional do cargo." - - - name: nome_ocorr_aposentadoria - description: "Descrição da ocorrência de aposentadoria." - - - name: sigla_nivel_cargo - description: "Sigla do nível do cargo ocupado." - - - name: tipo_vale_ar - description: "Tipo de auxílio-refeição concedido." - - - name: cod_ocorr_isencao_ir - description: "Código da ocorrência de isenção de imposto de renda." - - - name: dt_ini_ocorr_isencao_ir - description: "Data de início da ocorrência de isenção de IR." - - - name: nome_ocorr_isencao_ir - description: "Descrição da ocorrência de isenção de imposto de renda." - - - name: cod_uorg_lotacao - description: "Código da unidade de lotação do servidor." - - - name: nome_uorg_lotacao - description: "Nome da unidade de lotação do servidor." - - - name: sigla_uorg_lotacao - description: "Sigla da unidade de lotação do servidor." - - - name: dt_fim_ocorr_isencao_ir - description: "Data de término da isenção de IR." - - - name: cod_ocorr_exclusao - description: "Código da ocorrência de exclusão do servidor do sistema." - - - name: dt_ocorr_exclusao - description: "Data da ocorrência de exclusão do servidor." - - - name: nome_ocorr_exclusao - description: "Descrição da ocorrência de exclusão do servidor." - - - name: dt_uorg_lotacao - description: "Data da lotação na unidade organizacional atual." - - - name: cod_vale_transporte - description: "Código do benefício de vale transporte." - - - name: valor_vale_transporte - description: "Valor monetário do vale transporte." - - - name: dt_uorg_exercicio - description: "Data de início do exercício na unidade organizacional atual." - - - name: pontuacao_desempenho - description: > - Pontuação atribuída ao servidor conforme avaliação de desempenho. - Pode conter letras (A, B, C) ou valores numéricos, depende da origem. Mantido como string. - - - name: dt_ingest - description: "Data e hora (UTC-3 Brasília) em que os dados foram ingeridos da fonte original para a camada raw." - - - - name: dados_pa - description: > - Tabela bronze com dados de pensionistas e alimentados. - meta: - tags: - - bronze - columns: - - name: agencia_beneficiario - description: "Agência bancária do beneficiário." - - name: banco_beneficiario - description: "Banco do beneficiário." - - name: cod_orgao - description: "Código do órgão." - - name: conta_beneficiario - description: "Conta bancária do beneficiário." - - name: cpf_beneficiario - description: "CPF do beneficiário." - - name: matricula_servidor - description: "Matrícula do servidor instituidor da pensão." - - name: nome_beneficiario - description: "Nome do beneficiário." - - name: valor_ultima_pensao - description: "Valor da última pensão." - - name: cpf_servidor - description: "CPF do servidor instituidor da pensão." - - name: cod_vinculo_servidor - description: "Código do vínculo com o servidor." - - name: nome_alimentado - description: "Nome do alimentado." - - name: nome_vinculo_servidor - description: "Nome do vínculo com o servidor." - - name: dt_ingest - description: "Data e hora (UTC-3 Brasília) em que os dados foram ingeridos da fonte original para a camada raw." - - - name: dados_pessoais - description: > - Tabela bronze com dados pessoais dos servidores. - meta: - tags: - - bronze - columns: - - name: cod_cor - description: "Código da cor/raça." - - name: cod_estado_civil - description: "Código do estado civil." - - name: cod_nacionalidade - description: "Código da nacionalidade." - - name: cod_sexo - description: "Código do sexo." - - name: dt_nascimento - description: "Data de nascimento." - - name: grupo_sanguineo - description: "Grupo sanguíneo." - - name: nome_pessoa - description: "Nome da pessoa." - - name: nome_cor - description: "Nome da cor/raça." - - name: nome_estado_civil - description: "Nome do estado civil." - - name: nome_mae - description: "Nome da mãe." - - name: nome_municipio_nascimento - description: "Nome do município de nascimento." - - name: nome_nacionalidade - description: "Nome da nacionalidade." - - name: nome_pai - description: "Nome do pai." - - name: nome_sexo - description: "Nome do sexo." - - name: num_pispasep - description: "Número do PIS/PASEP." - - name: uf_nascimento - description: "UF de nascimento." - - name: cpf - description: "CPF do servidor." - - name: cod_deficiencia_fisica - description: "Código de deficiência física." - - name: nome_deficiencia_fisica - description: "Nome da deficiência física." - - name: dt_chegada_brasil - description: "Data de chegada ao Brasil." - - name: nome_pais_origem - description: "Nome do país de origem." - - name: dt_ingest - description: "Data e hora (UTC-3 Brasília) em que os dados foram ingeridos da fonte original para a camada raw." - - - name: dados_uorg - description: > - Tabela bronze com dados das Unidades Organizacionais (UORGs). - meta: - tags: - - bronze - columns: - - name: bairro_uorg - description: "Bairro da UORG." - - name: cep_uorg - description: "CEP da UORG." - - name: codigo_matricula - description: "Código de matrícula." - - name: codigo_municipio_uorg - description: "Código do município da UORG." - - name: codigo_orgao - description: "Código do órgão." - - name: codigo_orgao_uorg - description: "Código da UORG no órgão." - - name: email_uorg - description: "Email da UORG." - - name: tipo_endereco_uorg - description: "Tipo de endereço da UORG." - - name: logradouro_uorg - description: "Logradouro da UORG." - - name: nome_municipio_uorg - description: "Nome do município da UORG." - - name: nome_uorg - description: "Nome da UORG." - - name: telefone_uorg - description: "Telefone da UORG." - - name: numero_endereco_uorg - description: "Número do endereço da UORG." - - name: sigla_uorg - description: "Sigla da UORG." - - name: uf_uorg - description: "UF da UORG." - - name: cpf - description: "CPF associado à UORG." - - name: complemento_endereco_uorg - description: "Complemento do endereço da UORG." - - name: fax_uorg - description: "Fax da UORG." - - name: dt_ingest - description: "Data e hora (UTC-3 Brasília) em que os dados foram ingeridos da fonte original para a camada raw." - - - - name: estrutura_organizacional_cargos - description: > - Tabela gold contendo a estrutura organizacional de unidades com informações expandidas de cargos e instâncias. - Os dados foram transformados para extrair e normalizar os campos aninhados no JSON armazenado na coluna `cargos`. - A tabela inclui apenas uma instância por código, priorizando a de maior ordem de grandeza. - meta: - tags: - - bronze - columns: - - name: codigounidade - description: Código da unidade organizacional. - - name: nomeunidade - description: Nome completo da unidade organizacional. - - name: siglaunidade - description: Sigla da unidade organizacional. - - name: municipio - description: Município onde a unidade está localizada. - - name: uf - description: Unidade federativa (UF) correspondente ao município. - - name: denominacao - description: Denominação do cargo. - - name: funcao - description: Função associada à denominação do cargo. - - name: codigo_instancia - description: Código da instância do cargo na estrutura. - - name: nome_titular - description: Nome do servidor titular do cargo. - - name: cpf_titular - description: CPF do servidor titular do cargo (com apenas dígitos numéricos). - - name: ordem_grandeza - description: Nível hierárquico da unidade na estrutura, utilizado para escolher a instância mais relevante. - - name: dt_ingest - description: "Data e hora (UTC-3 Brasília) em que os dados foram ingeridos da fonte original para a camada raw." - - - - name: lista_servidores - description: > - Tabela bronze com a lista de servidores e suas UORGs. - meta: - tags: - - bronze - columns: - - name: cod_uorg - description: "Código da UORG." - - name: dt_ultima_transacao - description: "Data da última transação." - - name: cpf - description: "CPF do servidor." - - name: dt_ingest - description: "Data e hora (UTC-3 Brasília) em que os dados foram ingeridos da fonte original para a camada raw." - - - name: lista_uorgs - description: > - Tabela bronze com a lista de UORGs. - meta: - tags: - - bronze - columns: - - name: codigo - description: "Código da UORG." - - name: dt_ultima_transacao - description: "Data da última transação." - - name: nome - description: "Nome da UORG." - - name: dt_ingest - description: "Data e hora (UTC-3 Brasília) em que os dados foram ingeridos da fonte original para a camada raw." - - - name: terceirizados - description: > - Tabela gold contendo informações de trabalhadores terceirizados oriundos do sistema ComprasGov. - Inclui dados relacionados ao contrato, função, jornada, remuneração e benefícios, com tratamento de campos textuais e numéricos para padronização. - meta: - tags: - - bronze - columns: - - name: id - description: Identificador único do registro do trabalhador terceirizado. - - name: contrato_id - description: Identificador do contrato ao qual o trabalhador está vinculado. - - name: cpf - description: CPF do trabalhador, extraído da string `usuario`. - - name: nome - description: Nome do trabalhador, extraído da string `usuario`. - - name: funcao_id - description: Identificador da função exercida pelo trabalhador. - - name: descricao_complementar - description: Descrição complementar da função ou atividade do trabalhador. - - name: jornada - description: Quantidade de horas de jornada de trabalho semanal do trabalhador (convertido para numérico). - - name: unidade - description: Unidade organizacional onde o trabalhador presta serviço. - - name: salario - description: Valor do salário mensal do trabalhador (convertido para formato numérico padrão). - - name: custo - description: Custo total do trabalhador para a instituição (convertido para formato numérico padrão). - - name: escolaridade_id - description: Identificador do grau de escolaridade do trabalhador. - - name: data_inicio - description: Data de início do contrato do trabalhador, convertida para formato de data. - - name: data_fim - description: Data de término do contrato do trabalhador, convertida para formato de data. - - name: situacao - description: Situação atual do vínculo contratual do trabalhador (ativo, encerrado). - - name: aux_transporte - description: Valor mensal do auxílio transporte recebido pelo trabalhador (convertido para numérico). - - name: vale_alimentacao - description: Valor mensal do vale alimentação recebido pelo trabalhador (convertido para numérico). - - name: dt_ingest - description: "Data e hora (UTC-3 Brasília) em que os dados foram ingeridos da fonte original para a camada raw." - - - - name: unidade_organizacional - description: > - Tabela gold que representa a hierarquia das unidades organizacionais extraídas do sistema Siorg. - A hierarquia é construída de forma recursiva, partindo de uma unidade raiz definida manualmente. - A tabela traz dados estruturados sobre as unidades, seus vínculos parentais e o nível de profundidade hierárquica. - meta: - tags: - - bronze - columns: - - name: codigounidade - description: Código da unidade organizacional (sem prefixos de URI). - - name: codigounidadepai - description: Código da unidade organizacional pai, representando a hierarquia entre unidades. - - name: codigoorgaoentidade - description: Código do órgão ou entidade ao qual a unidade pertence. - - name: codigotipounidade - description: Código do tipo da unidade organizacional (departamento, secretaria). - - name: nome - description: Nome completo da unidade organizacional. - - name: sigla - description: Sigla da unidade organizacional. - - name: codigoesfera - description: Código da esfera governamental (federal, estadual, municipal). - - name: codigopoder - description: Código do poder ao qual a unidade está vinculada (Executivo, Judiciário). - - name: codigonaturezajuridica - description: Código da natureza jurídica da unidade. - - name: codigosubnaturezajuridica - description: Código da subnatureza jurídica da unidade. - - name: nivelnormatizacao - description: Nível de normatização da unidade organizacional. - - name: versaoconsulta - description: Número da versão da consulta no momento da extração dos dados. - - name: datafinalversaoconsulta - description: Data de finalização da versão da consulta. - - name: operacao - description: Tipo de operação registrada (inclusão, alteração, exclusão). - - name: codigounidadepaianterior - description: Código da unidade pai anterior (em caso de alteração estrutural). - - name: codigoorgaoentidadeanterior - description: Código do órgão/entidade anterior da unidade (em caso de mudança). - - name: ordem_grandeza - description: Nível hierárquico da unidade dentro da estrutura organizacional (quanto maior, mais profunda). - - name: caminho_unidade - description: Caminho hierárquico concatenado das siglas das unidades até o nível atual. - - name: dt_ingest - description: "Data e hora (UTC-3 Brasília) em que os dados foram ingeridos da fonte original para a camada raw." - - diff --git a/dbt/ipea/models/pessoas_dbt/bronze/terceirizados.sql b/dbt/ipea/models/pessoas_dbt/bronze/terceirizados.sql deleted file mode 100644 index fd5d5367..00000000 --- a/dbt/ipea/models/pessoas_dbt/bronze/terceirizados.sql +++ /dev/null @@ -1,21 +0,0 @@ -select - id, - contrato_id, - substring(usuario, '(.+) - ') as cpf, - substring(usuario, '- (.+)') as nome, - funcao_id, - descricao_complementar, - jornada::numeric as jornada, - unidade, - replace(replace(salario, '.', ''), ',', '.')::numeric(15, 2) as salario, - replace(replace(custo, '.', ''), ',', '.')::numeric(15, 2) as custo, - escolaridade_id, - to_date(data_inicio, 'YYYY-mm-dd') as data_inicio, - to_date(data_fim, 'YYYY-mm-dd') as data_fim, - situacao, - replace(replace(aux_transporte, '.', ''), ',', '.')::numeric(15, 2) as aux_transporte, - replace(replace(vale_alimentacao, '.', ''), ',', '.')::numeric( - 15, 2 - ) as vale_alimentacao, - (dt_ingest || '-03:00')::timestamptz as dt_ingest -from {{ source("compras_gov", "terceirizados") }} diff --git a/dbt/ipea/models/pessoas_dbt/bronze/unidade_organizacional.sql b/dbt/ipea/models/pessoas_dbt/bronze/unidade_organizacional.sql deleted file mode 100644 index ef0d04f1..00000000 --- a/dbt/ipea/models/pessoas_dbt/bronze/unidade_organizacional.sql +++ /dev/null @@ -1,42 +0,0 @@ -with recursive - fonte as ( - select - regexp_replace(codigounidade, '^.*/', '') as codigounidade, - regexp_replace(codigounidadepai, '^.*/', '') as codigounidadepai, - regexp_replace(codigoorgaoentidade, '^.*/', '') as codigoorgaoentidade, - regexp_replace(codigotipounidade, '^.*/', '') as codigotipounidade, - nome, - sigla, - regexp_replace(codigoesfera, '^.*/', '') as codigoesfera, - regexp_replace(codigopoder, '^.*/', '') as codigopoder, - regexp_replace(codigonaturezajuridica, '^.*/', '') as codigonaturezajuridica, - codigosubnaturezajuridica, - nivelnormatizacao, - versaoconsulta, - datafinalversaoconsulta, - operacao, - codigounidadepaianterior, - codigoorgaoentidadeanterior, - (dt_ingest || '-03:00')::timestamptz as dt_ingest - from {{ source("siorg", "unidade_organizacional") }} - ), - - unidades_raiz as (select '7' as codigounidade_raiz), - - hierarquia as ( - select f.*, 1 as ordem_grandeza, sigla as caminho_unidade - from fonte f - join unidades_raiz r on f.codigounidade = r.codigounidade_raiz - - union all - - select - f.*, - h.ordem_grandeza + 1 as ordem_grandeza, - h.caminho_unidade || '-' || lpad(f.sigla::text, 5, '0') as caminho_unidade - from fonte f - join hierarquia h on f.codigounidadepai = h.codigounidade - ) - -select * -from hierarquia diff --git a/dbt/ipea/models/pessoas_dbt/gold/aposentadorias_resumo.sql b/dbt/ipea/models/pessoas_dbt/gold/aposentadorias_resumo.sql deleted file mode 100644 index 5e0cf404..00000000 --- a/dbt/ipea/models/pessoas_dbt/gold/aposentadorias_resumo.sql +++ /dev/null @@ -1,34 +0,0 @@ --- Tabela contendo os aposentados e tempo de serviço --- Granularidade: cpf -with - - aposentados_extract as ( - select distinct - cpf, - nome_pessoa, - dt_ocorr_ingresso_serv_publico, - dt_ocorr_aposentadoria, - date_trunc('month', dt_ocorr_aposentadoria) as mes_aposentadoria, - nome_situacao_funcional, - nome_ocorr_aposentadoria, - nome_cargo, - sigla_nivel_cargo, - cod_classe || '-' || cod_padrao as classe_padrao, - dt_ingest - from {{ ref("servidores_detalhados") }} sd - where dt_ocorr_aposentadoria is not null - ) - -select - *, - age(dt_ocorr_aposentadoria, dt_ocorr_ingresso_serv_publico) as age, - extract( - year from age(dt_ocorr_aposentadoria, dt_ocorr_ingresso_serv_publico) - ) as diff_anos, - extract( - month from age(dt_ocorr_aposentadoria, dt_ocorr_ingresso_serv_publico) - ) as diff_meses, - extract( - days from age(dt_ocorr_aposentadoria, dt_ocorr_ingresso_serv_publico) - ) as diff_dias -from aposentados_extract diff --git a/dbt/ipea/models/pessoas_dbt/gold/cargos_consolidado.sql b/dbt/ipea/models/pessoas_dbt/gold/cargos_consolidado.sql deleted file mode 100644 index 96e000ee..00000000 --- a/dbt/ipea/models/pessoas_dbt/gold/cargos_consolidado.sql +++ /dev/null @@ -1,33 +0,0 @@ --- cargos siape + siorg --- ver logica para achar os cargos vagos e mudar essa tabela ! --- como o siorg lista todos os cargos, os que vierem null no siape provavelmente estão --- vagos -select - siorg.codigounidade as siorg_cod_unidade, - siorg.nomeunidade as siorg_nome_unidade, - siorg.siglaunidade as siorg_sigla_unidade, - siorg.municipio as siorg_municipio_unidade, - siorg.uf as siorg_uf_unidade, - siorg.denominacao as siorg_denominacao_cargo, - siorg.funcao as siorg_funcao, - siorg.codigo_instancia as siorg_cod_instancia_cargo, - siorg.cpf_titular as siorg_cpf_titular, - siorg.nome_titular as siorg_nome_titular, - - siape.cpf as siape_cpf, - siape.nome_pessoa as siape_nome_pessoa, - siape.nome_cargo as siape_nome_cargo_efetivo, - siape.nome_funcao as siape_nome_funcao_comissionada, - siape.cod_uorg_exercicio as siape_cod_uorg, - siape.nome_uorg_exercicio as siape_nome_uorg, - siape.sigla_uorg_exercicio as siape_sigla_uorg, - siape.uf_uorg as siape_uf_uorg, - siape.nome_situacao_funcional as siape_situacao_funcional, - greatest( - siorg.dt_ingest, - siape.dt_ingest - ) as dt_ingest - -from {{ ref("servidores_detalhados") }} siape -left join - {{ ref("estrutura_organizacional_cargos") }} siorg on siape.cpf = siorg.cpf_titular -- tabela siorg diff --git a/dbt/ipea/models/pessoas_dbt/gold/distribuicao_genero.sql b/dbt/ipea/models/pessoas_dbt/gold/distribuicao_genero.sql deleted file mode 100644 index 56b692f8..00000000 --- a/dbt/ipea/models/pessoas_dbt/gold/distribuicao_genero.sql +++ /dev/null @@ -1,9 +0,0 @@ --- Distribuição de servidores por gênero -select - nome_sexo as genero, - count(*) as quantidade_servidores, - count(*) * 1.0 / sum(count(*)) over () as percentual_distribuicao, - max(dt_ingest) as dt_ingest -from {{ ref("servidores_completos") }} -group by nome_sexo -order by percentual_distribuicao desc diff --git a/dbt/ipea/models/pessoas_dbt/gold/distribuicao_mapa_uf.sql b/dbt/ipea/models/pessoas_dbt/gold/distribuicao_mapa_uf.sql deleted file mode 100644 index 3736e2e9..00000000 --- a/dbt/ipea/models/pessoas_dbt/gold/distribuicao_mapa_uf.sql +++ /dev/null @@ -1,38 +0,0 @@ --- Modelo para gerar a distribuição geográfica de servidores por UF --- Retorna todos os estados brasileiros com suas respectivas contagens e percentuais -with - -- Obter todos os servidores com localização - servidores_localizacao as ( - select distinct - df.cpf, du.uf_uorg, du.nome_municipio_uorg, df.nome_situacao_funcional, - greatest(df.dt_ingest, du.dt_ingest) as dt_ingest - from {{ ref("dados_funcionais") }} df - inner join {{ ref("dados_uorg") }} du on df.sigla_uorg_exercicio = du.sigla_uorg - where du.uf_uorg is not null - ), - - -- Contar servidores por UF - contagem_por_uf as ( - select uf_uorg, count(distinct cpf) as valor, max(dt_ingest) as dt_ingest_uf - from servidores_localizacao - group by uf_uorg - ), - - -- Calcular totais para percentual - total_servidores as (select sum(valor) as total from contagem_por_uf) - --- Juntar todos os estados com suas contagens (0 para estados sem servidores) -select - eb.sigla_uf, - eb.nome_uf, - coalesce(cpu.valor, 0) as valor, - case - when coalesce(cpu.valor, 0) = 0 - then '0%' - else concat(round((coalesce(cpu.valor, 0) * 100.0 / ts.total), 0), '%') - end as percentual, - cpu.dt_ingest_uf as dt_ingest -from {{ ref("estados_brasil") }} eb -cross join total_servidores ts -left join contagem_por_uf cpu on eb.sigla_uf = cpu.uf_uorg -order by eb.sigla_uf diff --git a/dbt/ipea/models/pessoas_dbt/gold/distribuicao_raca_cor.sql b/dbt/ipea/models/pessoas_dbt/gold/distribuicao_raca_cor.sql deleted file mode 100644 index 5c5a884b..00000000 --- a/dbt/ipea/models/pessoas_dbt/gold/distribuicao_raca_cor.sql +++ /dev/null @@ -1,5 +0,0 @@ --- Distribuição de servidores por raça/cor -select nome_cor as cor_raca, count(nome_cor) as quantidade_servidores, max(dt_ingest) as dt_ingest -from {{ ref("servidores_completos") }} -group by nome_cor -order by quantidade_servidores desc diff --git a/dbt/ipea/models/pessoas_dbt/gold/distribuicao_situacao_funcional.sql b/dbt/ipea/models/pessoas_dbt/gold/distribuicao_situacao_funcional.sql deleted file mode 100644 index 4ff775b9..00000000 --- a/dbt/ipea/models/pessoas_dbt/gold/distribuicao_situacao_funcional.sql +++ /dev/null @@ -1,34 +0,0 @@ -with - dados_funcionais_enriquecidos as ( - select distinct - df.*, - case - when df.modalidade_pgd is null - then 'Não participa' - when df.modalidade_pgd = 'parcial' - then 'Parcial' - when df.modalidade_pgd = 'integral' - then 'Integral' - when df.modalidade_pgd = 'presencial' - then 'Presencial' - when df.modalidade_pgd = 'no exterior' - then 'No exterior' - end as pdg, - case - when df.nome_situacao_funcional = 'ATIVO EM OUTRO ORGAO' - then 'Ativo em outro órgão' - else df.sigla_uorg_exercicio - end as unidade_exercicio, - du.nome_municipio_uorg, - greatest(df.dt_ingest, du.dt_ingest) as dt_ingest_max - from {{ ref("dados_funcionais") }} df - inner join {{ ref("dados_uorg") }} du on df.sigla_uorg_exercicio = du.sigla_uorg - ) - -select - nome_situacao_funcional as situacao_funcional_original, - count(nome_situacao_funcional) as quantidade_servidores, - max(dt_ingest_max) as dt_ingest -from dados_funcionais_enriquecidos -group by nome_situacao_funcional -order by quantidade_servidores desc diff --git a/dbt/ipea/models/pessoas_dbt/gold/hierarquia.sql b/dbt/ipea/models/pessoas_dbt/gold/hierarquia.sql deleted file mode 100644 index 2cf041de..00000000 --- a/dbt/ipea/models/pessoas_dbt/gold/hierarquia.sql +++ /dev/null @@ -1,154 +0,0 @@ -with - - correcao_funcao as ( - select *, replace(funcao, ' ', '') as funcao_sigla - from {{ ref("estrutura_organizacional_cargos") }} - ), - - codigos_siorg as ( - select distinct - funcao_sigla, - eorg.nomeunidade, - eorg.codigounidade, - eorg.ordem_grandeza, - eorg.denominacao, - uo.codigounidadepai, - uo.caminho_unidade, - case - when eorg.siglaunidade = 'GABIN-IPEA' then 'GABIN' else siglaunidade - end as siglaunidade, - substring(funcao_sigla, length(funcao_sigla) - 2, 1) as categoria_cargo, - -- hierarquia do cargo está sendo definida a partir da fórmula: - -- (categoria do cargo * 1000) - nível do cargo - -- quanto menor a hierarquia, maior o cargo - right(funcao_sigla, 2) as nivel_cargo, - cast(substring(funcao_sigla, length(funcao_sigla) - 2, 1) as int) * 1000 - - cast(right(funcao, 2) as int) as hierarquia_cargo, - greatest(eorg.dt_ingest, uo.dt_ingest) as dt_ingest_siorg - from correcao_funcao as eorg - inner join - {{ ref("unidade_organizacional") }} as uo - on eorg.codigounidade = uo.codigounidade - ), - - codigos_siape as ( - select distinct - df.cod_funcao, - df.nome_uorg_exercicio, - df.sigla_uorg_exercicio, - df.nome_cargo, - df.matricula_siape, - df.cpf, - df.cpf_chefia_imediata, - df.cod_situacao_funcional, - df.nome_situacao_funcional, - dp.nome_pessoa, - dp.dt_nascimento, - dp.nome_sexo, - dp.nome_estado_civil, - dp.nome_nacionalidade, - dp.nome_cor, - dp.uf_nascimento, - dp.nome_municipio_nascimento, - uo.codigounidade as codigounidade_alternativa, - uo.caminho_unidade as caminho_unidade_alternativa, - uo.codigounidadepai as codigounidadepai_alternativa, - uo.ordem_grandeza as ordem_grandeza_alternativa, - substring(df.cod_funcao, 1, 1) || substring( - df.cod_funcao, length(df.cod_funcao) - 2, 3 - ) as codigo_combinacao_siape, - greatest(df.dt_ingest, uo.dt_ingest, uo.dt_ingest) as dt_ingest_siape - from {{ ref("dados_funcionais") }} as df - left join {{ ref("dados_pessoais") }} as dp on df.cpf = dp.cpf - left join - {{ ref("unidade_organizacional") }} as uo - on df.sigla_uorg_exercicio = uo.sigla - where dt_ocorr_aposentadoria is null and dt_ocorr_exclusao is null - ), - - -- select count(*) from codigos_siape; - codigo_siorg_combinado as ( - select - *, - substring(funcao_sigla, 1, 1) || substring( - funcao_sigla, length(funcao_sigla) - 2, 3 - ) as codigo_combinacao_siorg - from codigos_siorg - ), - - primeira_correlacao as ( - select - *, - case - when - siorg.codigo_combinacao_siorg is not null - and siape.codigo_combinacao_siape is not null - then 'inner' - when - siorg.codigo_combinacao_siorg is not null - and siape.codigo_combinacao_siape is null - then 'left' - when - siorg.codigo_combinacao_siorg is null - and siape.codigo_combinacao_siape is not null - then 'right' - end as tipo_correlacao - from codigo_siorg_combinado as siorg - full join - codigos_siape as siape - on siorg.codigo_combinacao_siorg = siape.codigo_combinacao_siape - and siorg.siglaunidade = siape.sigla_uorg_exercicio - ), - - -- select count(*) from primeira_correlacao - tabela_correlacao_cargos as ( - select distinct - pr.cod_funcao as codigo_siape, - pr.funcao_sigla as codigo_siorg, - pr.codigo_combinacao_siape, - pr.codigo_combinacao_siorg, - pr.matricula_siape as matricula_siape, - pr.cpf as cpf, - pr.cpf_chefia_imediata as cpf_chefia_imediata, - pr.cod_situacao_funcional as cod_situacao_funcional, - pr.nome_situacao_funcional as nome_situacao_funcional, - pr.hierarquia_cargo as hierarquia_cargo, - pr.nome_pessoa as servidor, - pr.dt_nascimento as dt_nascimento, - pr.nome_sexo as nome_sexo, - pr.nome_estado_civil as nome_estado_civil, - pr.nome_nacionalidade as nome_nacionalidade, - pr.nome_cor as nome_cor, - pr.uf_nascimento as uf_nascimento, - pr.nome_municipio_nascimento as nome_municipio_nascimento, - dp.nome_pessoa as nome_chefia, - coalesce( - cast(pr.codigounidade as text), cast(pr.codigounidade_alternativa as text) - ) as codigounidade, - coalesce( - cast(pr.codigounidadepai as text), - cast(pr.codigounidadepai_alternativa as text) - ) as codigounidadepai, - coalesce( - cast(pr.caminho_unidade as text), - cast(pr.caminho_unidade_alternativa as text) - ) as caminho_unidade, - coalesce( - cast(pr.ordem_grandeza as text), - cast(pr.ordem_grandeza_alternativa as text) - ) as ordem_grandeza, - coalesce(nomeunidade, nome_uorg_exercicio) as nomeunidade, - coalesce(siglaunidade, sigla_uorg_exercicio) as siglaunidade, - coalesce(denominacao, nome_cargo) as nome_cargo, - case - when cod_situacao_funcional = '04' then 'Nomeação livre' else 'Carreira' - end as servidores_carreira, - greatest(pr.dt_ingest_siorg, pr.dt_ingest_siape, dp.dt_ingest) as dt_ingest - from primeira_correlacao as pr - left join {{ ref("dados_pessoais") }} as dp on pr.cpf_chefia_imediata = dp.cpf - order by caminho_unidade, hierarquia_cargo - ) - -select * -from tabela_correlacao_cargos -where nome_situacao_funcional != 'ATIVO EM OUTRO ORGAO' diff --git a/dbt/ipea/models/pessoas_dbt/gold/kpis_servidores.sql b/dbt/ipea/models/pessoas_dbt/gold/kpis_servidores.sql deleted file mode 100644 index f4da198c..00000000 --- a/dbt/ipea/models/pessoas_dbt/gold/kpis_servidores.sql +++ /dev/null @@ -1,48 +0,0 @@ -with - total_servidores as ( - select count(distinct cpf) as total, max(dt_ingest) as dt_ingest - from {{ ref("dados_funcionais") }} - ), - - servidores_ativos as ( - select count(distinct cpf) as total, max(dt_ingest) as dt_ingest - from {{ ref("dados_funcionais") }} - where nome_situacao_funcional in ('ATIVO PERMANENTE') - ), - - aposentados as ( - select count(distinct cpf) as total, max(dt_ingest) as dt_ingest - from {{ ref("dados_funcionais") }} - where nome_situacao_funcional in ('APOSENTADO') - ), - - estagiarios as ( - select count(distinct cpf) as total, max(dt_ingest) as dt_ingest - from {{ ref("dados_funcionais") }} - where nome_situacao_funcional in ('ESTAGIARIO SIGEPE') - ), - - terceirizados as (select count(distinct id) as total, max(dt_ingest) as dt_ingest from {{ ref("terceirizados") }}) - -select 'total_servidores' as kpi, total as valor, dt_ingest -from total_servidores - -union all - -select 'servidores_ativos_permanentes' as kpi, total as valor, dt_ingest -from servidores_ativos - -union all - -select 'aposentados' as kpi, total as valor, dt_ingest -from aposentados - -union all - -select 'estagiarios' as kpi, total as valor, dt_ingest -from estagiarios - -union all - -select 'terceirizados' as kpi, total as valor, dt_ingest -from terceirizados diff --git a/dbt/ipea/models/pessoas_dbt/gold/resumo_quadro_pessoal.sql b/dbt/ipea/models/pessoas_dbt/gold/resumo_quadro_pessoal.sql deleted file mode 100644 index 368fb2b6..00000000 --- a/dbt/ipea/models/pessoas_dbt/gold/resumo_quadro_pessoal.sql +++ /dev/null @@ -1,9 +0,0 @@ -select - coalesce(nome_cargo, 'N/A') as cargo_efetivo, - coalesce(nome_sexo, 'N/A') as genero, - coalesce(nome_situacao_funcional, 'N/A') as situacao_funcional, - coalesce(uf_uorg, 'N/A') as localidade_uf, - count(distinct cpf) as quantidade_servidores, - max(dt_ingest) as dt_ingest -from {{ ref("servidores_detalhados") }} -group by 1, 2, 3, 4 diff --git a/dbt/ipea/models/pessoas_dbt/gold/schema.yml b/dbt/ipea/models/pessoas_dbt/gold/schema.yml deleted file mode 100644 index d4db042d..00000000 --- a/dbt/ipea/models/pessoas_dbt/gold/schema.yml +++ /dev/null @@ -1,364 +0,0 @@ -version: 2 - -models: - - # Gold - - name: aposentadorias_resumo - description: > - Tabela de resumo dos servidores aposentados, contendo informações detalhadas - sobre a data de ingresso no serviço público, data de aposentadoria e tempo - de serviço público calculado em anos, meses e dias. A granularidade da tabela - é por CPF, ou seja, cada linha representa um servidor aposentado único. - - meta: - tags: - - gold - columns: - - name: cpf - description: Número do CPF do servidor aposentado. - - name: nome_pessoa - description: Nome completo do servidor aposentado. - - name: dt_ocorr_ingresso_serv_publico - description: Data de ingresso do servidor no serviço público. - - name: dt_ocorr_aposentadoria - description: Data de aposentadoria do servidor. - - name: mes_aposentadoria - description: Mês da aposentadoria (arredondado para o primeiro dia do mês). - - name: nome_situacao_funcional - description: Situação funcional do servidor no momento da aposentadoria. - - name: nome_ocorr_aposentadoria - description: Tipo de ocorrência que levou à aposentadoria do servidor. - - name: nome_cargo - description: Cargo ocupado pelo servidor no momento da aposentadoria. - - name: sigla_nivel_cargo - description: Sigla do nível do cargo ocupado. - - name: classe_padrao - description: Classe e padrão do cargo, no formato "classe-padrão". - - name: age - description: Diferença completa entre as datas de ingresso e aposentadoria, em formato de intervalo. - - name: diff_anos - description: Quantidade de anos entre o ingresso no serviço público e a aposentadoria. - - name: diff_meses - description: Quantidade de meses entre o ingresso e a aposentadoria (ignora anos completos). - - name: diff_dias - description: Quantidade de dias entre o ingresso e a aposentadoria (ignora anos e meses completos). - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) mais recente de ingestão dos dados das tabelas fonte utilizadas neste modelo. - - - - - name: cargos_consolidado - description: > - Tabela que consolida informações de cargos ocupados e vagos no serviço público, - a partir da junção entre os dados do SIAPE (servidores ativos e detalhados) e - os dados do SIORG (estrutura de cargos disponíveis). Essa junção é feita com - base no CPF do titular do cargo. Quando os campos do SIAPE estão nulos, o cargo - provavelmente está vago. A tabela pode ser utilizada para identificar cargos - vagos por unidade organizacional. - - meta: - tags: - - gold - columns: - - name: siorg_cod_unidade - description: Código da unidade organizacional no SIORG. - - name: siorg_nome_unidade - description: Nome da unidade organizacional no SIORG. - - name: siorg_sigla_unidade - description: Sigla da unidade organizacional no SIORG. - - name: siorg_municipio_unidade - description: Município da unidade organizacional no SIORG. - - name: siorg_uf_unidade - description: Unidade federativa (UF) da unidade organizacional no SIORG. - - name: siorg_denominacao_cargo - description: Denominação do cargo conforme registrado no SIORG. - - name: siorg_funcao - description: Função comissionada associada ao cargo no SIORG. - - name: siorg_cod_instancia_cargo - description: Código da instância do cargo no SIORG. - - name: siorg_cpf_titular - description: CPF do titular do cargo segundo o SIORG. - - name: siorg_nome_titular - description: Nome do titular do cargo segundo o SIORG. - - - name: siape_cpf - description: CPF do servidor conforme os dados do SIAPE. - - name: siape_nome_pessoa - description: Nome completo do servidor no SIAPE. - - name: siape_nome_cargo_efetivo - description: Nome do cargo efetivo ocupado pelo servidor no SIAPE. - - name: siape_nome_funcao_comissionada - description: Nome da função comissionada ocupada pelo servidor no SIAPE. - - name: siape_cod_uorg - description: Código da unidade de exercício do servidor no SIAPE. - - name: siape_nome_uorg - description: Nome da unidade de exercício do servidor no SIAPE. - - name: siape_sigla_uorg - description: Sigla da unidade de exercício do servidor no SIAPE. - - name: siape_uf_uorg - description: Unidade federativa (UF) da unidade de exercício no SIAPE. - - name: siape_situacao_funcional - description: Situação funcional atual do servidor segundo o SIAPE. - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) mais recente de ingestão dos dados das tabelas fonte utilizadas neste modelo. - - - - - name: hierarquia - description: > - Tabela que correlaciona dados do SIAPE (dados funcionais e pessoais dos servidores) - com a estrutura organizacional do SIORG, atribuindo uma métrica de hierarquia aos cargos - com base na codificação da função. A hierarquia é determinada por uma fórmula baseada - na categoria e no nível do cargo. A tabela também indica se o cargo é de carreira ou de - nomeação livre, além de consolidar informações sobre o servidor e sua chefia imediata. - - meta: - tags: - - gold - columns: - - name: codigo_siape - description: Código da função no SIAPE. - - name: codigo_siorg - description: Código da função no SIORG, com espaços removidos. - - name: codigo_combinacao_siape - description: Código combinado derivado da função no SIAPE, usado para correlação. - - name: codigo_combinacao_siorg - description: Código combinado derivado da função no SIORG, usado para correlação. - - name: matricula_siape - description: Matrícula funcional do servidor no SIAPE. - - name: cpf - description: CPF do servidor. - - name: cpf_chefia_imediata - description: CPF da chefia imediata do servidor. - - name: cod_situacao_funcional - description: Código da situação funcional do servidor. - - name: nome_situacao_funcional - description: Descrição da situação funcional do servidor. - - name: hierarquia_cargo - description: Indicador numérico da hierarquia do cargo (quanto menor, maior o cargo). - - name: servidor - description: Nome do servidor ocupante do cargo. - - name: dt_nascimento - description: Data de nascimento do servidor. - - name: nome_sexo - description: Sexo do servidor. - - name: nome_estado_civil - description: Estado civil do servidor. - - name: nome_nacionalidade - description: Nacionalidade do servidor. - - name: nome_cor - description: Cor/raça do servidor. - - name: uf_nascimento - description: Unidade federativa de nascimento do servidor. - - name: nome_municipio_nascimento - description: Município de nascimento do servidor. - - name: nome_chefia - description: Nome da chefia imediata do servidor. - - name: codigounidade - description: Código da unidade organizacional associada ao cargo. - - name: codigounidadepai - description: Código da unidade organizacional pai (superior). - - name: caminho_unidade - description: Caminho hierárquico completo da unidade. - - name: ordem_grandeza - description: Nível hierárquico da unidade na estrutura organizacional. - - name: nomeunidade - description: Nome da unidade organizacional. - - name: siglaunidade - description: Sigla da unidade organizacional. - - name: nome_cargo - description: Nome ou denominação do cargo ocupado. - - name: servidores_carreira - description: Indica se o servidor está em cargo de carreira ou em nomeação livre. - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) mais recente de ingestão dos dados das tabelas fonte utilizadas neste modelo. - - - - name: resumo_quadro_pessoal - description: > - Tabela resumo com a distribuição dos servidores públicos por cargo efetivo, gênero, - situação funcional e unidade federativa da unidade de exercício (UF). A granularidade é agregada, - e cada linha representa uma combinação única desses atributos, com a respectiva contagem de servidores. - - meta: - tags: - - gold - columns: - - name: cargo_efetivo - description: > - Nome do cargo efetivo ocupado pelo servidor. Caso não informado, é preenchido com 'N/A'. - - name: genero - description: > - Gênero do servidor (masculino, feminino ou outro), conforme informado no cadastro pessoal. - Em casos de ausência de informação, é preenchido com 'N/A'. - - name: situacao_funcional - description: > - Situação funcional atual do servidor ( Ativo, Aposentado, Cedido, etc). - Valores ausentes são substituídos por 'N/A'. - - name: localidade_uf - description: > - Unidade Federativa (UF) da unidade organizacional onde o servidor exerce suas funções. - Valores ausentes são preenchidos com 'N/A'. - - name: quantidade_servidores - description: > - Quantidade total de servidores distintos (com base no CPF) que se enquadram na combinação dos atributos anteriores. - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) mais recente de ingestão dos dados das tabelas fonte utilizadas neste modelo. - - - - name: distribuicao_genero - description: > - Tabela agregada que apresenta a distribuição percentual de servidores por gênero, - enriquecida com informações de modalidade PGD, escolaridade e deficiência física. - A análise considera apenas servidores ativos com dados completos nas bases do SIAPE, - SIORG e dados de uorg. A granularidade é por gênero, com cálculo de percentual em relação ao total. - - meta: - tags: - - gold - columns: - - name: genero - description: Gênero do servidor (masculino, feminino, etc.) conforme cadastrado nos dados pessoais. - - name: quantidade_servidores - description: Quantidade total de servidores pertencentes a este gênero. - - name: percentual_distribuicao - description: > - Percentual de servidores deste gênero em relação ao total de servidores, - calculado como COUNT(*) * 1.0 / SUM(COUNT(*)) OVER (). - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) mais recente de ingestão dos dados das tabelas fonte utilizadas neste modelo. - - - - name: distribuicao_raca_cor - description: > - Tabela agregada que apresenta a distribuição de servidores por raça/cor, - enriquecida com informações de modalidade PGD, escolaridade e deficiência física. - A análise considera apenas servidores ativos com dados completos nas bases do SIAPE, - SIORG e dados de uorg. A granularidade é por raça/cor, ordenada pela quantidade de servidores. - - meta: - tags: - - gold - columns: - - name: cor_raca - description: > - Cor ou raça do servidor (branca, parda, preta, amarela, indígena, não informada) - conforme autodeclaração registrada nos dados pessoais do SIAPE. - - name: quantidade_servidores - description: Quantidade total de servidores que se autodeclararam desta cor/raça. - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) mais recente de ingestão dos dados das tabelas fonte utilizadas neste modelo. - - - - name: distribuicao_situacao_funcional - description: > - Tabela agregada que apresenta a distribuição de servidores por situação funcional, - categorizando e padronizando as diferentes situações registradas no SIAPE. - As situações funcionais são normalizadas em categorias como Ativo permanente, Cedido, - Requisitado, Aposentado, Pensionista, Cargo comissionado e Estagiário. - A análise inclui dados enriquecidos com informações de modalidade PGD e unidade organizacional. - - meta: - tags: - - gold - columns: - - name: situacao_funcional - description: > - Situação funcional normalizada do servidor (Ativo permanente, Cedido, Requisitado, - Aposentado, Pensionista, Cargo comissionado, Estagiário), derivada do campo - nome_situacao_funcional através de regras de categorização. - - name: situacao_funcional_original - description: > - Nome original da situação funcional conforme registrado no SIAPE, antes da normalização - (ATIVO PERMANENTE, ATIVO EM OUTRO ORGAO, APOSENTADO, etc.). - - name: quantidade_servidores - description: Quantidade total de servidores que se enquadram nesta combinação de situação funcional. - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) mais recente de ingestão dos dados das tabelas fonte utilizadas neste modelo. - - - - name: kpis_servidores - description: > - Tabela de KPIs (Key Performance Indicators) consolidados sobre o quadro de pessoal, - incluindo métricas de contagem total de servidores, servidores ativos permanentes, - aposentados, estagiários e terceirizados. Esta tabela fornece uma visão rápida e consolidada - dos principais indicadores quantitativos de recursos humanos da organização. - Cada linha representa um KPI específico com seu respectivo valor. - - meta: - tags: - - gold - - kpi - columns: - - name: kpi - description: > - Nome do indicador (total_servidores, servidores_ativos_permanentes, aposentados, - estagiarios, terceirizados). - - name: valor - description: > - Valor numérico do KPI, representando a contagem de CPFs ou IDs únicos conforme a métrica. - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) mais recente de ingestão dos dados das tabelas fonte utilizadas neste modelo. - - - - name: distribuicao_mapa_uf - description: > - Tabela com a distribuição geográfica completa de servidores por Unidade Federativa (UF). - Retorna todos os 27 estados brasileiros com suas respectivas contagens de servidores - e percentuais. Estados sem servidores aparecem com valor 0. Útil para visualizações - em mapas e análises de distribuição geográfica do quadro de pessoal. - - meta: - tags: - - gold - - dashboard - columns: - - name: sigla_uf - description: Sigla da Unidade Federativa (AC, AL, AM, AP, BA, CE, DF, ES, GO, MA, MG, MS, MT, PA, PB, PE, PI, PR, RJ, RN, RO, RR, RS, SC, SE, SP, TO). - - name: nome_uf - description: Nome completo da Unidade Federativa em maiúsculas. - - name: valor - description: Quantidade total de servidores com unidade de exercício neste estado. - - name: percentual - description: Percentual de servidores deste estado em relação ao total, formatado como string com símbolo '%'. - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) mais recente de ingestão dos dados das tabelas fonte utilizadas neste modelo. - - - - name: tabela_servidores_agregada - description: > - Tabela agregada de servidores com informações consolidadas por cargo, gênero, - situação funcional e localização (cidade/estado). Cada linha representa uma - combinação única desses atributos com a respectiva contagem de servidores. - Útil para análises detalhadas e exibição em tabelas de dashboard. - - meta: - tags: - - gold - - dashboard - columns: - - name: cargo - description: Nome do cargo ocupado pelo servidor. - - name: genero - description: Gênero do servidor normalizado (Masculino, Feminino). - - name: situacao - description: Situação funcional normalizada (Ativo Permanente, Aposentado, Ativo em outro órgão, Estagiário, Cedido/Requisitado). - - name: cidade - description: Nome do município da unidade de exercício formatado em título (primeira letra maiúscula). - - name: estado - description: Sigla da UF da unidade de exercício em maiúsculas. - - name: total - description: Quantidade total de servidores únicos (CPF) nesta combinação de atributos. - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) mais recente de ingestão dos dados das tabelas fonte utilizadas neste modelo. - diff --git a/dbt/ipea/models/pessoas_dbt/gold/tabela_servidores_agregada.sql b/dbt/ipea/models/pessoas_dbt/gold/tabela_servidores_agregada.sql deleted file mode 100644 index 2486bf81..00000000 --- a/dbt/ipea/models/pessoas_dbt/gold/tabela_servidores_agregada.sql +++ /dev/null @@ -1,61 +0,0 @@ --- Modelo para gerar tabela de servidores com agregação por cargo, gênero, situação e --- localização --- Agrupa os dados de servidores para visualização em tabelas detalhadas -with - servidores_completos as ( - select - df.cpf, - df.nome_cargo, - dp.nome_sexo as genero, - df.nome_situacao_funcional as situacao, - du.nome_municipio_uorg as cidade, - du.uf_uorg as estado, - greatest(df.dt_ingest, dp.dt_ingest, du.dt_ingest) as dt_ingest - from {{ ref("dados_funcionais") }} df - inner join {{ ref("dados_pessoais") }} dp on df.cpf = dp.cpf - inner join {{ ref("dados_uorg") }} du on df.sigla_uorg_exercicio = du.sigla_uorg - where - df.nome_cargo is not null - and dp.nome_sexo is not null - and df.nome_situacao_funcional is not null - and du.nome_municipio_uorg is not null - and du.uf_uorg is not null - ), - - servidores_agregados as ( - select - nome_cargo as cargo, - case - when upper(genero) = 'MASCULINO' - then 'Masculino' - when upper(genero) = 'FEMININO' - then 'Feminino' - else genero - end as genero, - case - when upper(situacao) = 'ATIVO PERMANENTE' - then 'Ativo Permanente' - when upper(situacao) = 'APOSENTADO' - then 'Aposentado' - when upper(situacao) = 'ATIVO EM OUTRO ORGAO' - then 'Ativo em outro órgão' - when upper(situacao) = 'ESTAGIARIO SIGEPE' - then 'Estagiário' - when - upper(situacao) like '%CEDIDO%' - or upper(situacao) like '%REQUISITADO%' - then 'Cedido/Requisitado' - else situacao - end as situacao, - initcap(cidade) as cidade, - upper(estado) as estado, - count(distinct cpf) as total, - max(dt_ingest) as dt_ingest - from servidores_completos - group by nome_cargo, genero, situacao, cidade, estado - ) - -select cargo, genero, situacao, cidade, estado, total, dt_ingest -from servidores_agregados -where total > 0 -order by total desc, cargo, genero diff --git a/dbt/ipea/models/pessoas_dbt/silver/afastamento_consolidado.sql b/dbt/ipea/models/pessoas_dbt/silver/afastamento_consolidado.sql deleted file mode 100644 index 6feb49e1..00000000 --- a/dbt/ipea/models/pessoas_dbt/silver/afastamento_consolidado.sql +++ /dev/null @@ -1,120 +0,0 @@ -with - - dados_afastamento_totais as ( - select distinct - adiantamento_salario_ferias, - ano_exercicio, - dt_fim, - dt_fim_aquisicao, - dt_ini, - dt_inicio_aquisicao, - dt_inicio_ferias_interrompidas, - dias_restantes, - gratificacao_natalina, - numero_parcela, - parcela_continuacao_interrupcao, - parcela_interrompida, - qtde_dias, - cpf, - cod_diploma_afastamento, - cod_ocorrencia, - dt_publicacao_afastamento, - desc_diploma_afastamento, - desc_ocorrencia, - numero_diploma_afastamento, - gr_matricula, - 'dados_afastamento' as origem_dados, -- identificar a fonte, - dt_ingest - from {{ ref("dados_afastamento") }} - - union all - - select distinct - adiantamento_salario_ferias, - ano_exercicio, - dt_fim, - dt_fim_aquisicao, - dt_ini, - dt_inicio_aquisicao, - dt_inicio_ferias_interrompidas, - dias_restantes, - gratificacao_natalina, - numero_parcela, - parcela_continuacao_interrupcao, - parcela_interrompida, - qtde_dias, - cpf, - cod_diploma_afastamento, - cod_ocorrencia, - dt_publicacao_afastamento, - desc_diploma_afastamento, - desc_ocorrencia, - numero_diploma_afastamento, - null as gr_matricula, -- não tem na afastamneto historico ... - 'afastamento_historico' as origem_dados, -- identificar a fonte, - dt_ingest - from {{ ref("afastamento_historico") }} - ), - - nomes_dt as (select distinct nome_pessoa, cpf from {{ ref("dados_pessoais") }}), - - funcoes_chefia as ( - select distinct cpf, cod_funcao, sigla_uorg_exercicio - from {{ ref("dados_funcionais") }} - ), - - -- Retirando duplicatas entre afastamento_historico e dados_afastamento - grupamentos as ( - select *, rank() over (partition by cpf order by dt_ini) as ordenacao - from dados_afastamento_totais - ), - - prioridades as ( - select - *, - row_number() over ( - partition by cpf, ordenacao - order by - case - when origem_dados = 'dados_afastamento' - then 1 - when origem_dados = 'afastamento_historico' - then 2 - end - ) as prioridade - from grupamentos - ), - - resultado as ( - select - adiantamento_salario_ferias, - ano_exercicio, - dt_fim, - dt_fim_aquisicao, - dt_ini, - dt_inicio_aquisicao, - dt_inicio_ferias_interrompidas, - dias_restantes, - gratificacao_natalina, - numero_parcela, - parcela_continuacao_interrupcao, - parcela_interrompida, - qtde_dias, - cpf, - cod_diploma_afastamento, - cod_ocorrencia, - dt_publicacao_afastamento, - desc_diploma_afastamento, - desc_ocorrencia, - numero_diploma_afastamento, - gr_matricula, - origem_dados, - dt_ingest - from prioridades - where prioridade = 1 - ) - -select * -from resultado -left join nomes_dt using (cpf) -left join funcoes_chefia using (cpf) diff --git a/dbt/ipea/models/pessoas_dbt/silver/quantitativo_alocados_ocupados.sql b/dbt/ipea/models/pessoas_dbt/silver/quantitativo_alocados_ocupados.sql deleted file mode 100644 index a1f3ba38..00000000 --- a/dbt/ipea/models/pessoas_dbt/silver/quantitativo_alocados_ocupados.sql +++ /dev/null @@ -1,108 +0,0 @@ -with - siape_sem_duplicatas as (select distinct * from {{ ref("dados_funcionais") }}), - siorg_sem_duplicatas as ( - select distinct * from {{ ref("estrutura_organizacional_cargos") }} - ), - - codigos_siorg as ( - select funcao, nomeunidade, siglaunidade, denominacao, count(*) as qtd_vagas_cargo, max(dt_ingest) as dt_ingest - from siorg_sem_duplicatas - group by funcao, nomeunidade, siglaunidade, denominacao - ), - - codigos_siape as ( - select - cod_funcao, - nome_uorg_exercicio, - sigla_uorg_exercicio, - nome_cargo, - count(*) as qtd_vagas_ocupadas, - max(dt_ingest) as dt_ingest - from siape_sem_duplicatas - where cod_funcao is not null and dt_ocorr_aposentadoria is null - group by cod_funcao, nome_uorg_exercicio, sigla_uorg_exercicio, nome_cargo - ), - - codigo_siorg_combinado as ( - select - replace(funcao, ' ', '') as funcao, - nomeunidade, - case - when siglaunidade = 'GABIN-IPEA' then 'GABIN' else siglaunidade - end as siglaunidade, - denominacao, - substring(replace(funcao, ' ', ''), 1, 1) || substring( - replace(funcao, ' ', ''), length(replace(funcao, ' ', '')) - 2, 3 - ) as codigo_combinacao_siorg, - qtd_vagas_cargo, - dt_ingest - from codigos_siorg - ), - - codigo_siape_combinado as ( - select - cod_funcao, - nome_uorg_exercicio, - sigla_uorg_exercicio, - nome_cargo, - substring(cod_funcao, 1, 1) || substring( - cod_funcao, length(cod_funcao) - 2, 3 - ) as codigo_combinacao_siape, - qtd_vagas_ocupadas, - dt_ingest - from codigos_siape - ), - - primeira_correlacao as ( - select - siorg.funcao, - siorg.nomeunidade, - siorg.siglaunidade, - siorg.denominacao, - siorg.codigo_combinacao_siorg, - siorg.qtd_vagas_cargo, - siape.cod_funcao, - siape.nome_uorg_exercicio, - siape.sigla_uorg_exercicio, - siape.nome_cargo, - siape.codigo_combinacao_siape, - siape.qtd_vagas_ocupadas, - greatest(siorg.dt_ingest, siape.dt_ingest) as dt_ingest, - case - when - siorg.codigo_combinacao_siorg is not null - and siape.codigo_combinacao_siape is not null - then 'inner' - when - siorg.codigo_combinacao_siorg is not null - and siape.codigo_combinacao_siape is null - then 'left' - when - siorg.codigo_combinacao_siorg is null - and siape.codigo_combinacao_siape is not null - then 'right' - end as tipo_correlacao - from codigo_siorg_combinado as siorg - full join - codigo_siape_combinado as siape - on siorg.codigo_combinacao_siorg = siape.codigo_combinacao_siape - and siorg.siglaunidade = siape.sigla_uorg_exercicio - ) - -select - cod_funcao as codigo_siape, - funcao as codigo_siorg, - coalesce(nomeunidade, nome_uorg_exercicio) as nomeunidade, - coalesce(siglaunidade, sigla_uorg_exercicio) as siglaunidade, - coalesce(denominacao, nome_cargo) as nome_cargo, - qtd_vagas_cargo, - coalesce(qtd_vagas_ocupadas, 0) as qtd_vagas_ocupadas, - case - when qtd_vagas_cargo is null - then null - when qtd_vagas_ocupadas is null - then qtd_vagas_cargo - else (qtd_vagas_cargo - qtd_vagas_ocupadas) - end as qtd_cargos_vagos, - dt_ingest -from primeira_correlacao diff --git a/dbt/ipea/models/pessoas_dbt/silver/schema.yml b/dbt/ipea/models/pessoas_dbt/silver/schema.yml deleted file mode 100644 index 879c8e8f..00000000 --- a/dbt/ipea/models/pessoas_dbt/silver/schema.yml +++ /dev/null @@ -1,335 +0,0 @@ -version: 2 - -models: - - - # Silver - - name: afastamento_consolidado - description: > - Tabela gold que consolida os registros de afastamento dos servidores, integrando as fontes - `dados_afastamento` e `afastamento_historico`, com enriquecimento de informações vindas de - `dados_pessoais` (nome do servidor) e `dados_funcionais` (função e unidade de exercício). - O processo inclui deduplicação inteligente priorizando os registros mais confiáveis, - utilizando lógica de ranking e partição por CPF e data de início do afastamento. - meta: - tags: - - silver - columns: - - name: adiantamento_salario_ferias - description: Indica se houve adiantamento de salário junto às férias no período do afastamento. - - name: ano_exercicio - description: Ano de exercício a que o afastamento se refere. - - name: dt_fim - description: Data de término do afastamento. - - name: dt_fim_aquisicao - description: Data final do período aquisitivo das férias relacionadas ao afastamento. - - name: dt_ini - description: Data de início do afastamento. - - name: dt_inicio_aquisicao - description: Data inicial do período aquisitivo de férias. - - name: dt_inicio_ferias_interrompidas - description: Data de início das férias interrompidas, se houver. - - name: dias_restantes - description: Quantidade de dias restantes de férias ou afastamento. - - name: gratificacao_natalina - description: Indica se houve gratificação natalina no período do afastamento. - - name: numero_parcela - description: Número da parcela relacionada ao afastamento. - - name: parcela_continuacao_interrupcao - description: Indica se o afastamento é continuação ou interrupção de uma parcela anterior. - - name: parcela_interrompida - description: Indica se a parcela foi interrompida. - - name: qtde_dias - description: Quantidade total de dias do afastamento. - - name: cpf - description: CPF do servidor. - - name: cod_diploma_afastamento - description: Código do diploma legal que ampara o afastamento. - - name: cod_ocorrencia - description: Código da ocorrência de afastamento. - - name: dt_publicacao_afastamento - description: Data de publicação do afastamento no diário oficial ou sistema correspondente. - - name: desc_diploma_afastamento - description: Descrição textual do diploma legal de afastamento. - - name: desc_ocorrencia - description: Descrição da ocorrência relacionada ao afastamento. - - name: numero_diploma_afastamento - description: Número do diploma legal do afastamento. - - name: gr_matricula - description: Número da matrícula do servidor no sistema GRH, quando disponível. - - name: origem_dados - description: Origem do dado de afastamento (`dados_afastamento` ou `afastamento_historico`). - - name: nome_pessoa - description: Nome completo do servidor, obtido a partir da tabela de dados pessoais. - - name: cod_funcao - description: Código da função de chefia ou cargo de confiança ocupado pelo servidor no momento do afastamento. - - name: sigla_uorg_exercicio - description: Sigla da unidade organizacional onde o servidor exercia suas funções. - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) mais recente de ingestão dos dados das tabelas fonte utilizadas neste modelo. - - - - - name: quantitativo_alocados_ocupados - description: > - Tabela gold que consolida e compara os quantitativos de cargos ocupados e cargos previstos - em funções de chefia, correlacionando os dados dos sistemas SIAPE e SIORG. A lógica aplica - uma combinação heurística de códigos de função com base na estrutura dos códigos e siglas - das unidades organizacionais, com objetivo de identificar inconsistências, sobras ou - vacâncias entre as vagas disponíveis e as efetivamente ocupadas. - meta: - tags: - - silver - columns: - - name: codigo_siape - description: Código da função do servidor registrado no SIAPE (`cod_funcao`), representando funções ocupadas. - - name: codigo_siorg - description: Código da função de chefia conforme registrado no SIORG (`funcao`), representando vagas previstas. - - name: nomeunidade - description: Nome da unidade organizacional, obtido da base SIORG ou SIAPE (com prioridade para SIORG). - - name: siglaunidade - description: Sigla da unidade organizacional, unificada a partir das duas fontes (com prioridade para SIORG). - - name: nome_cargo - description: Nome ou denominação do cargo/função de chefia, com base em SIORG ou SIAPE. - - name: qtd_vagas_cargo - description: Quantidade de vagas previstas para o cargo de chefia na estrutura organizacional (dados do SIORG). - - name: qtd_vagas_ocupadas - description: Quantidade de cargos de chefia efetivamente ocupados, com base nos registros de servidores no SIAPE. - - name: qtd_cargos_vagos - description: > - Diferença entre o número de vagas previstas (`qtd_vagas_cargo`) e as ocupadas (`qtd_vagas_ocupadas`). - Indica o total de cargos vagos. Retorna `null` se a quantidade de vagas previstas não estiver disponível. - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) mais recente de ingestão dos dados das tabelas fonte utilizadas neste modelo. - - - - name: servidores_detalhados - description: > - Tabela gold que consolida dados pessoais, funcionais, educacionais e organizacionais dos servidores. - Integra informações de múltiplas fontes do SIAPE, combinando registros de identificação, vínculo funcional, - escolaridade, endereço da unidade de exercício e metadados de transações. Essa visão é útil para análises - completas do perfil dos servidores ativos e inativos, permitindo estudos sociodemográficos, funcionais e - institucionais detalhados. - meta: - tags: - - silver - columns: - # Dados pessoais - - name: cpf - description: CPF do servidor, utilizado como chave primária de junção entre as bases. - - name: nome_pessoa - description: Nome completo do servidor. - - name: dt_nascimento - description: Data de nascimento do servidor. - - name: nome_cor - description: Cor/raça autodeclarada do servidor. - - name: nome_estado_civil - description: Estado civil declarado. - - name: nome_mae - description: Nome da mãe do servidor. - - name: nome_pai - description: Nome do pai do servidor. - - name: nome_municipio_nascimento - description: Município de nascimento do servidor. - - name: nome_nacionalidade - description: Nacionalidade declarada. - - name: nome_sexo - description: Sexo/gênero do servidor. - - # Dados funcionais - - name: matricula_siape - description: Matrícula SIAPE do servidor. - - name: nome_funcao - description: Nome da função de chefia ou cargo comissionado exercido, se houver. - - name: cod_funcao - description: Código da função exercida. - - name: nome_cargo - description: Nome do cargo efetivo. - - name: cod_cargo - description: Código do cargo efetivo. - - name: nome_jornada - description: Jornada de trabalho do servidor. - - name: dt_ingresso_funcao - description: Data de ingresso na função atual. - - name: nome_regime_juridico - description: Regime jurídico do vínculo funcional. - - name: nome_situacao_funcional - description: Situação funcional (ativo, cedido, aposentado etc). - - name: participa_pgd - description: Indica se o servidor participa do Programa de Gestão (teletrabalho). - - # Escolaridade e titulação - - name: nome_escolaridade_principal - description: Nível de escolaridade mais elevado do servidor. - - name: nome_titulacao_principal - description: Título acadêmico mais elevado do servidor ( mestrado, doutorado). - - # Unidade organizacional - - name: nome_uorg_exercicio - description: Nome da unidade organizacional onde o servidor exerce atualmente. - - name: sigla_uorg_exercicio - description: Sigla da unidade de exercício. - - name: nome_uorg_lotacao - description: Nome da unidade de lotação original. - - name: sigla_uorg_lotacao - description: Sigla da unidade de lotação. - - name: nome_orgao_funcional - description: Nome do órgão funcional ao qual o servidor está vinculado. - - name: sigla_orgao_funcional - description: Sigla do órgão funcional. - - # Endereço da unidade - - name: logradouro_uorg - description: Nome do logradouro da unidade. - - name: numero_endereco_uorg - description: Número do endereço da unidade. - - name: complemento_endereco_uorg - description: Complemento do endereço. - - name: bairro_uorg - description: Bairro onde a unidade está localizada. - - name: cep_uorg - description: CEP da unidade. - - name: nome_municipio_uorg - description: Município da unidade. - - name: uf_uorg - description: Unidade federativa da unidade. - - # Contatos institucionais - - name: email_institucional - description: Email institucional do servidor. - - name: email_servidor - description: Email alternativo do servidor. - - name: email_chefia_imediata - description: Email da chefia imediata. - - name: telefone_uorg - description: Telefone da unidade de exercício. - - name: fax_uorg - description: Fax da unidade de exercício. - - # Metadados e auditoria - - name: ident_unica_funcional - description: Identificador único funcional, usado para rastreamento interno. - - name: dt_ultima_transacao_servidor - description: Data da última transação registrada no sistema para o servidor. - - # Informações complementares - - name: cod_ocorr_aposentadoria - description: Código da ocorrência de aposentadoria (se houver). - - name: dt_ocorr_aposentadoria - description: Data da aposentadoria. - - name: cod_vale_transporte - description: Código do vale transporte. - - name: valor_vale_transporte - description: Valor mensal do vale transporte recebido. - - name: pontuacao_desempenho - description: Pontuação de desempenho do servidor, se aplicável. - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) mais recente de ingestão dos dados das tabelas fonte utilizadas neste modelo. - - - - - - name: tabela_correlacao_cargos - description: > - Tabela final que correlaciona cargos entre os sistemas SIAPE e SIORG, utilizando - combinações de códigos e unidades organizacionais. Cada linha representa um servidor - com informações enriquecidas da função e da chefia, além da hierarquia do cargo e - dados pessoais básicos. Essa tabela é útil para analisar discrepâncias, estruturar - a hierarquia funcional e verificar se as funções atribuídas no SIAPE estão - corretamente refletidas no SIORG. - - meta: - tags: - - silver - columns: - - name: codigo_siape - description: Código da função no SIAPE. - - name: codigo_siorg - description: Código da função no SIORG. - - name: codigo_combinacao_siape - description: Código combinado utilizado para comparar cargos no SIAPE. - - name: codigo_combinacao_siorg - description: Código combinado utilizado para comparar cargos no SIORG. - - name: matricula_siape - description: Matrícula do servidor no sistema SIAPE. - - name: cpf - description: CPF do servidor titular do cargo. - - name: cpf_chefia_imediata - description: CPF da chefia imediata do servidor. - - name: cod_situacao_funcional - description: Código da situação funcional do servidor no SIAPE. - - name: nome_situacao_funcional - description: Descrição da situação funcional. - - name: hierarquia_cargo - description: Valor numérico que representa a posição hierárquica do cargo. Quanto menor, mais alto o cargo. - - name: servidor - description: Nome do servidor titular do cargo. - - name: dt_nascimento - description: Data de nascimento do servidor. - - name: nome_sexo - description: Sexo do servidor. - - name: nome_estado_civil - description: Estado civil do servidor. - - name: nome_nacionalidade - description: Nacionalidade do servidor. - - name: nome_cor - description: Cor/raça autodeclarada pelo servidor. - - name: uf_nascimento - description: Unidade Federativa (UF) de nascimento. - - name: nome_municipio_nascimento - description: Município de nascimento do servidor. - - name: nome_chefia - description: Nome da chefia imediata, obtido pelo CPF da chefia. - - name: codigounidade - description: Código da unidade organizacional onde o cargo está lotado. - - name: codigounidadepai - description: Código da unidade organizacional imediatamente superior. - - name: caminho_unidade - description: Caminho hierárquico da unidade organizacional, representando sua posição na estrutura. - - name: ordem_grandeza - description: Nível de profundidade da unidade na hierarquia institucional. - - name: nomeunidade - description: Nome da unidade organizacional. - - name: siglaunidade - description: Sigla da unidade organizacional. - - name: nome_cargo - description: Denominação do cargo ocupado, conforme SIAPE ou SIORG. - - name: servidores_carreira - description: Classificação se o cargo é de carreira ou nomeação livre. - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) mais recente de ingestão dos dados das tabelas fonte utilizadas neste modelo. - - - - name: unidades_organizacionais_siorg_siape - description: > - Tabela que correlaciona as unidades organizacionais do SIAPE e do SIORG, - com base na correspondência entre os códigos e siglas das unidades. - Essa tabela é utilizada para identificar quais unidades estão presentes - em ambos os sistemas, apenas no SIAPE ou apenas no SIORG. - - meta: - tags: - - silver - columns: - - name: nome_unidade - description: Nome da unidade organizacional, proveniente do SIAPE ou SIORG. - - name: sigla_uorg - description: Sigla da unidade organizacional. Pode vir do SIAPE (dados_uorg) ou do SIORG (unidade_organizacional). - - name: codigo_unidade_siape - description: Código da unidade organizacional segundo o SIAPE (extraído de dados_uorg). - - name: codigo_unidade_siorg - description: Código da unidade organizacional segundo o SIORG (coluna codigounidade). - - name: tipo_correlacao - description: > - Tipo de correspondência encontrada entre os sistemas: - - "ambos": unidade presente no SIAPE e SIORG. - - "apenas_siorg": presente apenas no SIORG. - - "apenas_siape": presente apenas no SIAPE. - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) mais recente de ingestão dos dados das tabelas fonte utilizadas neste modelo. - diff --git a/dbt/ipea/models/pessoas_dbt/silver/servidores_completos.sql b/dbt/ipea/models/pessoas_dbt/silver/servidores_completos.sql deleted file mode 100644 index b92ada3d..00000000 --- a/dbt/ipea/models/pessoas_dbt/silver/servidores_completos.sql +++ /dev/null @@ -1,101 +0,0 @@ --- Modelo intermediário que centraliza os enriquecimentos de dados de servidores --- Combina informações de hierarquia, dados funcionais, organizacionais e pessoais --- Este modelo evita duplicação de código nos modelos gold -with - hierarquia_enriquecida as ( - select - ph.codigo_siape, - ph.codigo_siorg, - ph.codigo_combinacao_siape, - ph.codigo_combinacao_siorg, - ph.matricula_siape, - ph.cpf, - ph.cpf_chefia_imediata, - ph.cod_situacao_funcional, - ph.nome_situacao_funcional, - ph.hierarquia_cargo, - ph.servidor, - ph.dt_nascimento, - ph.nome_sexo, - ph.nome_estado_civil, - ph.nome_nacionalidade, - ph.nome_cor, - ph.uf_nascimento, - ph.nome_municipio_nascimento, - ph.nome_chefia, - ph.codigounidade, - ph.codigounidadepai, - ph.caminho_unidade, - ph.ordem_grandeza, - ph.nomeunidade, - ph.siglaunidade, - ph.nome_cargo, - ph.servidores_carreira, - ph.dt_ingest as dt_ingest_ph, - df.dt_ingest as dt_ingest_df, - case - when df.modalidade_pgd is null - then 'Não participa' - when df.modalidade_pgd = 'parcial' - then 'Parcial' - when df.modalidade_pgd = 'integral' - then 'Integral' - when df.modalidade_pgd = 'presencial' - then 'Presencial' - when df.modalidade_pgd = 'no exterior' - then 'No exterior' - end as pdg, - case - when ph.nome_situacao_funcional = 'ATIVO EM OUTRO ORGAO' - then 'Ativo em outro órgão' - else siglaunidade - end as unidade_exercicio - from {{ ref("hierarquia") }} ph - inner join {{ ref("dados_funcionais") }} df on ph.cpf = df.cpf - ), - - servidores_enriquecidos as ( - select distinct ph.*, du.nome_municipio_uorg, du.dt_ingest as dt_ingest_du - from hierarquia_enriquecida ph - inner join {{ ref("dados_uorg") }} du on ph.siglaunidade = du.sigla_uorg - order by caminho_unidade, hierarquia_cargo - ) - -select distinct - se.codigo_siape, - se.codigo_siorg, - se.codigo_combinacao_siape, - se.codigo_combinacao_siorg, - se.matricula_siape, - se.cpf, - se.cpf_chefia_imediata, - se.cod_situacao_funcional, - se.nome_situacao_funcional, - se.hierarquia_cargo, - se.servidor, - se.dt_nascimento, - se.nome_sexo, - se.nome_estado_civil, - se.nome_nacionalidade, - se.nome_cor, - se.uf_nascimento, - se.nome_municipio_nascimento, - se.nome_chefia, - se.codigounidade, - se.codigounidadepai, - se.caminho_unidade, - se.ordem_grandeza, - se.nomeunidade, - se.siglaunidade, - se.nome_cargo, - se.servidores_carreira, - se.pdg, - se.unidade_exercicio, - se.nome_municipio_uorg, - sd.cod_escolaridade_principal, - sd.nome_escolaridade_principal, - sd.nome_deficiencia_fisica, - sd.nome_cargo as nome_cargo_emprego, - greatest(se.dt_ingest_ph, se.dt_ingest_df, se.dt_ingest_du, sd.dt_ingest) as dt_ingest -from servidores_enriquecidos se -inner join {{ ref("servidores_detalhados") }} sd on se.cpf = sd.cpf diff --git a/dbt/ipea/models/pessoas_dbt/silver/servidores_detalhados.sql b/dbt/ipea/models/pessoas_dbt/silver/servidores_detalhados.sql deleted file mode 100644 index 03a04a6e..00000000 --- a/dbt/ipea/models/pessoas_dbt/silver/servidores_detalhados.sql +++ /dev/null @@ -1,159 +0,0 @@ -with - educacao_principal as ( - select cpf, cod_escolaridade, nome_escolaridade, cod_titulacao, nome_titulacao, dt_ingest as dt_ingest_ep - from {{ ref("dados_escolares") }} - ), - uorg_completo as ( - select - du.bairro_uorg, - du.cep_uorg, - du.codigo_matricula, - du.codigo_municipio_uorg, - du.codigo_orgao, - du.codigo_orgao_uorg, - du.email_uorg, - du.tipo_endereco_uorg, - du.logradouro_uorg, - du.nome_municipio_uorg, - du.nome_uorg, - du.telefone_uorg, - du.numero_endereco_uorg, - du.sigla_uorg, - du.uf_uorg, - du.cpf, - du.complemento_endereco_uorg, - du.fax_uorg, - du.dt_ingest as dt_ingest_du - -- lu.dt_ultima_transacao AS dt_ultima_transacao_uorg, os codigos não batem e a - -- informação aparentemente ja existe... - -- lu.nome AS nome_uorg_lista - from {{ ref("dados_uorg") }} du - -- LEFT JOIN {{ ref('lista_uorgs') }} lu - ) -select - dp.cpf, - dp.nome_pessoa, - dp.dt_nascimento, - dp.grupo_sanguineo, - dp.nome_cor, - dp.cod_cor, - dp.nome_estado_civil, - dp.cod_estado_civil, - dp.nome_mae, - dp.nome_pai, - dp.nome_municipio_nascimento, - dp.nome_nacionalidade, - dp.cod_nacionalidade, - dp.nome_sexo, - dp.cod_sexo, - dp.num_pispasep, - dp.uf_nascimento, - dp.cod_deficiencia_fisica, - dp.nome_deficiencia_fisica, - dp.dt_chegada_brasil, - dp.nome_pais_origem, - - df.cod_atividade_funcao, - df.cod_funcao, - df.cod_jornada, - df.cod_ocorr_ingresso_orgao, - df.cod_ocorr_ingresso_serv_publico, - df.cod_orgao as cod_orgao_funcional, - df.cod_padrao, - df.cod_situacao_funcional, - df.cod_uorg_exercicio, - df.cod_upag, - df.cod_orgao_origem, - df.cpf_chefia_imediata, - df.dt_exercicio_no_orgao, - df.dt_fim_vale_ar, - df.dt_ingresso_funcao, - df.dt_ocorr_ingresso_orgao, - df.dt_ocorr_ingresso_serv_publico, - df.email_chefia_imediata, - df.email_institucional, - df.email_servidor, - df.ident_unica as ident_unica_funcional, - df.matricula_siape, - df.modalidade_pgd, - df.nome_atividade_funcao, - df.nome_chefe_uorg, - df.nome_funcao, - df.nome_jornada, - df.nome_ocorr_ingresso_orgao, - df.nome_ocorr_ingresso_serv_publico, - df.nome_orgao as nome_orgao_funcional, - df.nome_regime_juridico, - df.nome_situacao_funcional, - df.nome_uorg_exercicio, - df.nome_upag, - df.participa_pgd, - df.percentual_ts, - df.sigla_orgao as sigla_orgao_funcional, - df.sigla_orgao_origem, - df.sigla_regime_juridico, - df.sigla_uorg_exercicio, - df.sigla_upag, - df.cod_cargo, - df.cod_classe, - df.cod_ocorr_aposentadoria, - df.dt_ini_vale_ar, - df.dt_ocorr_aposentadoria, - df.nome_cargo, - df.nome_classe, - df.nome_ocorr_aposentadoria, - df.sigla_nivel_cargo, - df.tipo_vale_ar, - df.cod_ocorr_isencao_ir, - df.dt_ini_ocorr_isencao_ir, - df.nome_ocorr_isencao_ir, - df.cod_uorg_lotacao, - df.nome_uorg_lotacao, - df.sigla_uorg_lotacao, - df.dt_fim_ocorr_isencao_ir, - df.cod_ocorr_exclusao, - df.dt_ocorr_exclusao, - df.nome_ocorr_exclusao, - df.dt_uorg_lotacao, - df.cod_vale_transporte, - df.valor_vale_transporte, - df.dt_uorg_exercicio, - df.pontuacao_desempenho, - - ep.nome_escolaridade as nome_escolaridade_principal, - ep.cod_escolaridade as cod_escolaridade_principal, - ep.nome_titulacao as nome_titulacao_principal, - ep.cod_titulacao as cod_titulacao_principal, - - ls.dt_ultima_transacao as dt_ultima_transacao_servidor, - - uorg_c.bairro_uorg, - uorg_c.cep_uorg, - uorg_c.codigo_matricula, - uorg_c.codigo_municipio_uorg, - uorg_c.codigo_orgao, - uorg_c.codigo_orgao_uorg, - uorg_c.email_uorg, - uorg_c.tipo_endereco_uorg, - uorg_c.logradouro_uorg, - uorg_c.nome_municipio_uorg, - uorg_c.nome_uorg, - uorg_c.telefone_uorg, - uorg_c.numero_endereco_uorg, - uorg_c.sigla_uorg, - uorg_c.uf_uorg, - uorg_c.complemento_endereco_uorg, - uorg_c.fax_uorg, - - greatest( - dp.dt_ingest, - df.dt_ingest, - ep.dt_ingest_ep, - uorg_c.dt_ingest_du - ) as dt_ingest - -from {{ ref("dados_pessoais") }} dp -left join {{ ref("dados_funcionais") }} df on dp.cpf = df.cpf -left join educacao_principal ep on dp.cpf = ep.cpf -left join {{ ref("lista_servidores") }} ls on dp.cpf = ls.cpf -left join uorg_completo uorg_c on dp.cpf = uorg_c.cpf diff --git a/dbt/ipea/models/pessoas_dbt/silver/tabela_correlacao_cargos.sql b/dbt/ipea/models/pessoas_dbt/silver/tabela_correlacao_cargos.sql deleted file mode 100644 index aa5e5bf3..00000000 --- a/dbt/ipea/models/pessoas_dbt/silver/tabela_correlacao_cargos.sql +++ /dev/null @@ -1,187 +0,0 @@ -with - - correcao_funcao as ( - select - *, - replace(funcao, ' ', '') as funcao_sigla, - dt_ingest as dt_ingest_estrutura - from {{ ref("estrutura_organizacional_cargos") }} - ), - - codigos_siorg as ( - select distinct - funcao_sigla, - eorg.nomeunidade, - eorg.codigounidade, - eorg.ordem_grandeza, - eorg.denominacao, - eorg.codigo_instancia, - eorg.dt_ingest_estrutura, - uo.codigounidadepai, - uo.caminho_unidade, - case - when eorg.siglaunidade = 'GABIN-IPEA' then 'GABIN' else siglaunidade - end as siglaunidade, - substring(funcao_sigla, length(funcao_sigla) - 2, 1) as categoria_cargo, - -- hierarquia do cargo está sendo definida a partir da fórmula: - -- (categoria do cargo * 1000) - nível do cargo - -- quanto menor a hierarquia, maior o cargo - right(funcao_sigla, 2) as nivel_cargo, - cast(substring(funcao_sigla, length(funcao_sigla) - 2, 1) as int) * 1000 - - cast(right(funcao, 2) as int) as hierarquia_cargo, - uo.dt_ingest as dt_ingest_uorg - from correcao_funcao as eorg - inner join - {{ ref("unidade_organizacional") }} as uo - on eorg.codigounidade = uo.codigounidade - ), - - codigos_siape as ( - select distinct - df.cod_funcao, - df.nome_uorg_exercicio, - df.sigla_uorg_exercicio, - df.nome_cargo, - df.matricula_siape, - df.cpf, - df.cpf_chefia_imediata, - df.cod_situacao_funcional, - df.nome_situacao_funcional, - dp.nome_pessoa, - dp.dt_nascimento, - dp.nome_sexo, - dp.nome_estado_civil, - dp.nome_nacionalidade, - dp.nome_cor, - dp.uf_nascimento, - dp.nome_municipio_nascimento, - uo.codigounidade as codigounidade_alternativa, - uo.caminho_unidade as caminho_unidade_alternativa, - uo.codigounidadepai as codigounidadepai_alternativa, - uo.ordem_grandeza as ordem_grandeza_alternativa, - substring(df.cod_funcao, 1, 1) || substring( - df.cod_funcao, length(df.cod_funcao) - 2, 3 - ) as codigo_combinacao_siape, - df.dt_ingest as dt_ingest_funcionais, - dp.dt_ingest as dt_ingest_pessoais, - uo.dt_ingest as dt_ingest_uorg_alt - from {{ ref("dados_funcionais") }} as df - left join {{ ref("dados_pessoais") }} as dp on df.cpf = dp.cpf - left join - {{ ref("unidade_organizacional") }} as uo - on df.sigla_uorg_exercicio = uo.sigla - where dt_ocorr_aposentadoria is null and cod_funcao is not null - ), - - -- select count(*) from codigos_siape; - codigo_siorg_combinado as ( - select - *, - substring(funcao_sigla, 1, 1) || substring( - funcao_sigla, length(funcao_sigla) - 2, 3 - ) as codigo_combinacao_siorg - from codigos_siorg - ), - - numeracao_cargos_siape as ( - select - *, - row_number() over ( - partition by codigo_combinacao_siape, sigla_uorg_exercicio - order by sigla_uorg_exercicio - ) as ordem_siape - from codigos_siape - ), - - numeracao_cargos_siorg as ( - select - *, - row_number() over ( - partition by codigo_combinacao_siorg, siglaunidade order by siglaunidade - ) as ordem_siorg - from codigo_siorg_combinado - ), - - primeira_correlacao as ( - select - *, - case - when - siorg.codigo_combinacao_siorg is not null - and siape.codigo_combinacao_siape is not null - then 'inner' - when - siorg.codigo_combinacao_siorg is not null - and siape.codigo_combinacao_siape is null - then 'left' - when - siorg.codigo_combinacao_siorg is null - and siape.codigo_combinacao_siape is not null - then 'right' - end as tipo_correlacao - from numeracao_cargos_siorg as siorg - full join - numeracao_cargos_siape as siape - on siorg.codigo_combinacao_siorg = siape.codigo_combinacao_siape - and siorg.siglaunidade = siape.sigla_uorg_exercicio - and siorg.ordem_siorg = siape.ordem_siape - ), - - -- select count(*) from primeira_correlacao - tabela_correlacao_cargos as ( - select distinct - pr.cod_funcao as codigo_siape, - pr.funcao_sigla as codigo_siorg, - pr.codigo_combinacao_siape, - pr.codigo_combinacao_siorg, - pr.matricula_siape as matricula_siape, - pr.cpf as cpf, - pr.cpf_chefia_imediata as cpf_chefia_imediata, - pr.cod_situacao_funcional as cod_situacao_funcional, - pr.nome_situacao_funcional as nome_situacao_funcional, - pr.hierarquia_cargo as hierarquia_cargo, - pr.nome_pessoa as servidor, - pr.dt_nascimento as dt_nascimento, - pr.nome_sexo as nome_sexo, - pr.nome_estado_civil as nome_estado_civil, - pr.nome_nacionalidade as nome_nacionalidade, - pr.nome_cor as nome_cor, - pr.uf_nascimento as uf_nascimento, - pr.nome_municipio_nascimento as nome_municipio_nascimento, - dp.nome_pessoa as nome_chefia, - coalesce( - cast(pr.codigounidade as text), cast(pr.codigounidade_alternativa as text) - ) as codigounidade, - coalesce( - cast(pr.codigounidadepai as text), - cast(pr.codigounidadepai_alternativa as text) - ) as codigounidadepai, - coalesce( - cast(pr.caminho_unidade as text), - cast(pr.caminho_unidade_alternativa as text) - ) as caminho_unidade, - coalesce( - cast(pr.ordem_grandeza as text), - cast(pr.ordem_grandeza_alternativa as text) - ) as ordem_grandeza, - coalesce(nomeunidade, nome_uorg_exercicio) as nomeunidade, - coalesce(siglaunidade, sigla_uorg_exercicio) as siglaunidade, - coalesce(denominacao, nome_cargo) as nome_cargo, - case - when cod_situacao_funcional = '04' then 'Nomeação livre' else 'Carreira' - end as servidores_carreira, - - greatest( - pr.dt_ingest_estrutura, - pr.dt_ingest_uorg, - pr.dt_ingest_funcionais, - pr.dt_ingest_pessoais, - pr.dt_ingest_uorg_alt - ) as dt_ingest - from primeira_correlacao as pr - left join {{ ref("dados_pessoais") }} as dp on pr.cpf_chefia_imediata = dp.cpf - order by caminho_unidade, hierarquia_cargo - ) - -select * -from tabela_correlacao_cargos diff --git a/dbt/ipea/models/pessoas_dbt/silver/unidades_organizacionais_siorg_siape.sql b/dbt/ipea/models/pessoas_dbt/silver/unidades_organizacionais_siorg_siape.sql deleted file mode 100644 index b5af5981..00000000 --- a/dbt/ipea/models/pessoas_dbt/silver/unidades_organizacionais_siorg_siape.sql +++ /dev/null @@ -1,54 +0,0 @@ -with - preparacao as ( - select - du.codigo_orgao::integer as codigo_orgao, - du.codigo_orgao_uorg as combinacao_codigo_lista, - (right(du.codigo_orgao_uorg, 7))::integer as codigo_lista_uorg, - du.sigla_uorg as sigla_uorg, - max(du.dt_ingest) as dt_ingest_du - from {{ ref("dados_uorg") }} du - group by 1, 2, 3, 4 - ), - - join_lista_uorgo_dados_uorg as ( - select - p.codigo_orgao, - p.combinacao_codigo_lista, - p.codigo_lista_uorg, - p.sigla_uorg, - p.dt_ingest_du, - lu.dt_ultima_transacao, - lu.nome as nome_unidade, - max(lu.dt_ingest) as dt_ingest_lu - from preparacao p - join {{ ref("lista_uorgs") }} lu on p.codigo_lista_uorg = lu.codigo - group by 1, 2, 3, 4, 5, 6, 7 - ), - - unidade_organizacional as ( - select distinct - *, case when sigla = 'GABIN-IPEA' then 'GABIN' else sigla end as sigla_unidade - from {{ ref("unidade_organizacional") }} - ), - - tabela_corralacao_uorgs as ( - select - coalesce(a.nome_unidade, uo.nome) as nome_unidade, - coalesce(a.sigla_uorg, sigla_unidade) as sigla_uorg, - a.codigo_lista_uorg as codigo_unidade_siape, - uo.codigounidade as codigo_unidade_siorg, - greatest(a.dt_ingest_du, a.dt_ingest_lu) as dt_ingest, - case - when a.nome_unidade is null and uo.nome is not null - then 'apenas_siorg' - when a.nome_unidade is not null and uo.nome is null - then 'apenas_siape' - when a.nome_unidade is not null and uo.nome is not null - then 'ambos' - end as tipo_correlacao - from join_lista_uorgo_dados_uorg a - full join unidade_organizacional uo on a.sigla_uorg = uo.sigla_unidade - ) - -select * -from tabela_corralacao_uorgs diff --git a/dbt/ipea/models/sources.yml b/dbt/ipea/models/sources.yml deleted file mode 100644 index aa4c3af6..00000000 --- a/dbt/ipea/models/sources.yml +++ /dev/null @@ -1,76 +0,0 @@ -version: 2 - -sources: - - name: compras_gov - schema: compras_gov - tables: - - name: contratos - - name: faturas - - name: empenhos - - name: cronograma - - name: terceirizados - - - name: siafi - schema: siafi - tables: - - name: empenhos_tesouro - - name: estagios_tesouro - - name: nc_tesouro - - name: pf_tesouro - - name: visao_orcamentaria_total - - - name: transfere_gov - schema: transfere_gov - tables: - - name: notas_de_credito - - name: planos_acao - - name: programacao_financeira - - name: programas - - name: siape - schema: siape - tables: - - name: lista_uorgs - - name: lista_servidores - - name: dados_uorg - - name: dados_pessoais - - name: dados_pa - - name: dados_funcionais - - name: dados_financeiros - - name: dados_escolares - - name: dados_dependentes - - name: dados_curriculo - - name: dados_afastamento - - name: afastamento_historico - - - name: siorg - schema: siorg - tables: - - name: estrutura_organizacional_cargos - - name: cargos_funcao - - name: unidade_organizacional - - - name: transferegov_emendas - schema: transferegov_emendas - tables: - - name: programas_especiais - - name: planos_acao_especiais - - name: empenhos_especiais - - name: ordens_bancarias_especiais - - name: historico_pagamentos_especiais - - name: plano_trabalho_especial - - name: documentos_habeis_especiais - - name: relatorio_gestao_especial - - name: relatorios_gestao_novo_especial - - name: executor_especial - - name: metas_especiais - - name: finalidades_especiais - - - name: dados_abertos - schema: camara_deputados - tables: - - name: deputados - - - name: senado_federal - schema: senado_federal - tables: - - name: senadores diff --git a/dbt/ipea/models/ted_dbt/bronze/nc_tesouro.sql b/dbt/ipea/models/ted_dbt/bronze/nc_tesouro.sql deleted file mode 100644 index a12edbbf..00000000 --- a/dbt/ipea/models/ted_dbt/bronze/nc_tesouro.sql +++ /dev/null @@ -1,31 +0,0 @@ -with - - notas_credito as ( - select - {{ target.schema }}.parse_date(emissao_mes) as emissao_mes, - to_date(emissao_dia, 'DD/MM/YYYY') as emissao_dia, - nc, - nc_transferencia, - nc_fonte_recursos, - nc_fonte_recursos_descricao, - ptres, - nc_evento, - nc_evento_descricao as nc_evento_descr, - ug_responsavel, - ug_responsavel_descricao, - natureza_despesa as nc_natureza_despesa, - natureza_despesa_detalhada as nc_natureza_despesa_descricao, - plano_interno, - plano_detalhado_descricao1, - plano_detalhado_descricao2, - favorecido_doc, - favorecido_doc_descricao, - replace(nc_valor_linha, ',', '.')::numeric(15, 2) as nc_valor_linha, - {{ parse_financial_value("movimento_liquido") }} as movimento_liquido, - (dt_ingest || '-03:00')::timestamptz as dt_ingest - from {{ source("siafi", "nc_tesouro") }} - ) - --- -select * -from notas_credito diff --git a/dbt/ipea/models/ted_dbt/bronze/pf_tesouro.sql b/dbt/ipea/models/ted_dbt/bronze/pf_tesouro.sql deleted file mode 100644 index c9b0d593..00000000 --- a/dbt/ipea/models/ted_dbt/bronze/pf_tesouro.sql +++ /dev/null @@ -1,32 +0,0 @@ -with - - programacoes_financeira as ( - select - {{ target.schema }}.parse_date(emissao_mes) as emissao_mes, - to_date(emissao_dia, 'DD/MM/YYYY') as emissao_dia, - ug_emitente, - ug_emitente_descricao, - ug_favorecido, - ug_favorecido_descricao, - pf_evento, - pf_evento_descricao, - right(pf, 12) as pf, - pf_inscricao, - pf_acao, - pf_acao_descricao, - pf_fonte_recursos, - pf_fonte_recursos_descricao, - pf_vinculacao_pagamento, - pf_vinculacao_pagamento_descricao, - pf_categoria_gasto, - pf_recurso, - pf_recurso_descricao, - doc_observacao, - replace(pf_valor_linha, ',', '.')::numeric(15, 2) as pf_valor_linha, - (dt_ingest || '-03:00')::timestamptz as dt_ingest - from {{ source("siafi", "pf_tesouro") }} - ) - --- -select * -from programacoes_financeira diff --git a/dbt/ipea/models/ted_dbt/bronze/planos_acao.sql b/dbt/ipea/models/ted_dbt/bronze/planos_acao.sql deleted file mode 100644 index 5ffb801a..00000000 --- a/dbt/ipea/models/ted_dbt/bronze/planos_acao.sql +++ /dev/null @@ -1,36 +0,0 @@ -with - - planos_acao as ( - select - id_plano_acao, - id_programa, - sigla_unidade_descentralizada, - case - when sigla_unidade_descentralizada = 'IPEA' - then 'beneficiario' - else 'emitente' - end as ted_beneficiario_emitente, - unidade_descentralizada, - sigla_unidade_responsavel_execucao, - unidade_responsavel_execucao, - vl_total_plano_acao::numeric(15, 2) as vl_total_plano_acao, - to_date(dt_inicio_vigencia, 'YYYY-mm-dd') as dt_inicio_vigencia, - to_date(dt_fim_vigencia, 'YYYY-mm-dd') as dt_fim_vigencia, - tx_objeto_plano_acao, - tx_justificativa_plano_acao, - in_forma_execucao_direta, - in_forma_execucao_particulares, - in_forma_execucao_descentralizada, - tx_situacao_plano_acao, - aa_ano_plano_acao, - vl_beneficiario_especifico::numeric(15, 2) as vl_beneficiario_especifico, - vl_chamamento_publico::numeric(15, 2) as vl_chamamento_publico, - sq_instrumento, - aa_instrumento, - (dt_ingest || '-03:00')::timestamptz as dt_ingest - from {{ source("transfere_gov", "planos_acao") }} - ) - --- -select * -from planos_acao diff --git a/dbt/ipea/models/ted_dbt/bronze/schema.yml b/dbt/ipea/models/ted_dbt/bronze/schema.yml deleted file mode 100644 index 2e2bfc38..00000000 --- a/dbt/ipea/models/ted_dbt/bronze/schema.yml +++ /dev/null @@ -1,234 +0,0 @@ -version: 2 - -models: - - # TED DBT - - name: pf_tesouro - description: > - Esta tabela contém registros de Programações Financeiras extraídas do SIAFI, detalhando informações como tipo de programação, data de execução e valor. - A tabela é atualizada diariamente e reflete as autorizações de movimentação financeira no âmbito da execução orçamentária federal. - meta: - tags: - - bronze - columns: - - name: emissao_mes - description: > - Mês de emissão da Programação Financeira. - - name: emissao_dia - description: > - Dia de emissão da Programação Financeira. - - name: ug_emitente - description: > - Código da Unidade Gestora responsável pela emissão da Programação Financeira. - - name: ug_emitente_descricao - description: > - Nome ou descrição da Unidade Gestora emitente da Programação Financeira. - - name: ug_favorecido - description: > - Código da Unidade Gestora favorecida pela Programação Financeira. - - name: ug_favorecido_descricao - description: > - Nome ou descrição da Unidade Gestora favorecida pela Programação Financeira. - - name: pf_evento - description: > - Código do evento contábil associado à Programação Financeira, representando a natureza da transação. - - name: pf_evento_descricao - description: > - Descrição do evento contábil vinculado à Programação Financeira. - - name: pf - description: > - Número identificador único da Programação Financeira. - - name: pf_inscricao - description: > - Número de inscrição da Programação Financeira, utilizado para controle e acompanhamento. - - name: pf_acao - description: > - Código da ação orçamentária associada à Programação Financeira. - - name: pf_acao_descricao - description: > - Descrição da ação orçamentária vinculada à Programação Financeira. - - name: pf_fonte_recursos - description: > - Código da fonte de recursos associada à Programação Financeira, indicando a origem dos recursos utilizados. - - name: pf_fonte_recursos_descricao - description: > - Descrição textual da fonte de recursos vinculada à Programação Financeira. - - name: pf_vinculacao_pagamento - description: > - Código da vinculação de pagamento associada à Programação Financeira. - - name: pf_vinculacao_pagamento_descricao - description: > - Descrição da vinculação de pagamento vinculada à Programação Financeira. - - name: pf_categoria_gasto - description: > - Código da categoria de gasto associada à Programação Financeira, conforme classificação orçamentária. - - name: pf_recurso - description: > - Código do recurso associado à Programação Financeira. - - name: pf_recurso_descricao - description: > - Descrição do recurso vinculado à Programação Financeira. - - name: doc_observacao - description: > - Observações adicionais relacionadas à Programação Financeira. - - name: pf_valor_linha - description: > - Valor monetário individual da linha da Programação Financeira. - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) em que os dados foram ingeridos da fonte original para a camada raw. - data_tests: - - verificacao_tipagem: - nome_tabela: 'ted.pf_tesouro' - nome_coluna: 'emissao_dia' - tipo_esperado: 'date' - - verificacao_tipagem: - nome_tabela: 'ted.pf_tesouro' - nome_coluna: 'pf_valor_linha' - tipo_esperado: 'numeric' - - - name: nc_tesouro - description: > - Esta tabela registra informações detalhadas sobre as Notas de Crédito emitidas no âmbito da execução orçamentária e financeira do governo federal. - As Notas de Crédito representam autorizações para a realização de despesas, sendo fundamentais para o controle e acompanhamento da execução orçamentária. - meta: - tags: - - bronze - columns: - - name: emissao_mes - description: > - Mês de emissão da Nota de Crédito. - - name: emissao_dia - description: > - Dia de emissão da Nota de Crédito. - - name: nc - description: > - Número identificador único da Nota de Crédito. - - name: nc_transferencia - description: > - Indicador de que a Nota de Crédito refere-se a uma transferência de recursos entre unidades gestoras. - - name: nc_fonte_recursos - description: > - Código da fonte de recursos associada à Nota de Crédito, indicando a origem dos recursos utilizados. - - name: nc_fonte_recursos_descricao - description: > - Descrição textual da fonte de recursos vinculada à Nota de Crédito. - - name: ptres - description: > - Código do Plano Interno de Trabalho (PTRES) relacionado à Nota de Crédito, utilizado para detalhar a alocação dos recursos. - - name: nc_evento - description: > - Código do evento contábil associado à Nota de Crédito, representando a natureza da transação. - - name: nc_evento_descricao - description: > - Descrição do evento contábil vinculado à Nota de Crédito. - - name: ug_responsavel - description: > - Código da Unidade Gestora responsável pela emissão da Nota de Crédito. - - name: ug_responsavel_descricao - description: > - Nome ou descrição da Unidade Gestora responsável pela emissão da Nota de Crédito. - - name: natureza_despesa - description: > - Código da natureza da despesa associada à Nota de Crédito, conforme classificação orçamentária. - - name: natureza_despesa_detalhada - description: > - Descrição detalhada da natureza da despesa vinculada à Nota de Crédito. - - name: plano_interno - description: > - Código do plano interno relacionado à Nota de Crédito, utilizado para controle interno da execução orçamentária. - - name: plano_detalhado_descricao1 - description: > - Primeira descrição detalhada do plano interno associado à Nota de Crédito. - - name: plano_detalhado_descricao2 - description: > - Segunda descrição detalhada do plano interno associado à Nota de Crédito. - - name: favorecido_doc - description: > - Documento de identificação (CPF ou CNPJ) do favorecido pela Nota de Crédito. - - name: favorecido_doc_descricao - description: > - Nome ou razão social do favorecido identificado na Nota de Crédito. - - name: nc_valor_linha - description: > - Valor monetário individual da linha da Nota de Crédito. - - name: movimento_liquido - description: > - Valor líquido do movimento financeiro associado à Nota de Crédito, após deduções ou acréscimos aplicáveis. - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) em que os dados foram ingeridos da fonte original para a camada raw. - - - name: planos_acao - description: > - Esta tabela armazena informações detalhadas sobre os Planos de Ação vinculados a programas públicos. - Ela consolida dados sobre as unidades envolvidas na execução, prazos de vigência, valores, justificativas, - formas de execução e instrumentos utilizados. Serve como base para o acompanhamento, análise e auditoria - da implementação de ações públicas em diferentes formatos de execução. - meta: - tags: - - bronze - columns: - - name: id_plano_acao - description: > - Identificador único do Plano de Ação. - - name: id_programa - description: > - Identificador único do programa ao qual o Plano de Ação está vinculado. - - name: sigla_unidade_descentralizada - description: > - Sigla da unidade descentralizada responsável pelo Plano de Ação. - - name: unidade_descentralizada - description: > - Nome completo da unidade descentralizada responsável pelo Plano de Ação. - - name: sigla_unidade_responsavel_execucao - description: > - Sigla da unidade responsável pela execução do Plano de Ação. - - name: unidade_responsavel_execucao - description: > - Nome completo da unidade responsável pela execução do Plano de Ação. - - name: vl_total_plano_acao - description: > - Valor total previsto para execução do Plano de Ação. - - name: dt_inicio_vigencia - description: > - Data de início da vigência do Plano de Ação. - - name: dt_fim_vigencia - description: > - Data final da vigência do Plano de Ação. - - name: tx_objeto_plano_acao - description: > - Descrição do objeto do Plano de Ação, informando seu propósito e escopo. - - name: tx_justificativa_plano_acao - description: > - Justificativa para a elaboração e execução do Plano de Ação. - - name: in_forma_execucao_direta - description: > - Indicador booleano que sinaliza se a execução do plano ocorrerá de forma direta. - - name: in_forma_execucao_particulares - description: > - Indicador booleano que sinaliza se a execução contará com a participação de particulares. - - name: in_forma_execucao_descentralizada - description: > - Indicador booleano que sinaliza se a execução será realizada de forma descentralizada. - - name: tx_situacao_plano_acao - description: > - Situação atual do Plano de Ação ( em elaboração, aprovado, em execução, concluído). - - name: aa_ano_plano_acao - description: > - Ano de referência do Plano de Ação. - - name: vl_beneficiario_especifico - description: > - Valor destinado especificamente a beneficiários definidos no Plano de Ação. - - name: vl_chamamento_publico - description: > - Valor previsto para execução por meio de chamamento público. - - name: sq_instrumento - description: > - Código sequencial do instrumento jurídico ou administrativo associado ao Plano de Ação. - - name: aa_instrumento - description: > - Ano de referência do instrumento associado ao Plano de Ação. - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) em que os dados foram ingeridos da fonte original para a camada raw. diff --git a/dbt/ipea/models/ted_dbt/gold/schema.yml b/dbt/ipea/models/ted_dbt/gold/schema.yml deleted file mode 100644 index 415d8375..00000000 --- a/dbt/ipea/models/ted_dbt/gold/schema.yml +++ /dev/null @@ -1,64 +0,0 @@ -version: 2 - -models: - - - name: ted_resumo_orcamentario - description: > - Tabela de consolidação orçamentária e financeira por Plano de Ação, baseada em informações de valores firmados, orçamentos recebidos e devolvidos, empenhos, despesas e transferências financeiras. - Os dados são integrados de diferentes fontes (notas de crédito, empenhos e programações financeiras) para fornecer um resumo abrangente da execução orçamentária e financeira de transferências intergovernamentais. - meta: - tags: - - gold - columns: - - name: plano_acao - description: > - Identificador único do Plano de Ação associado aos registros orçamentários e financeiros. - - name: num_transf - description: > - Número da transferência utilizado como chave de ligação entre diferentes fontes de dados. - - name: sigla_unidade_descentralizada - description: > - Sigla da Unidade Descentralizada responsável pelo Plano de Ação. - - name: ted_beneficiario_emitente - description: > - Identifica se a Unidade do Plano de Ação é a beneficiária ou a emitente dos recursos da TED (Transferência Voluntária). Valores possíveis: 'beneficiario', 'emitente' ou 'nao_indicado'. - - name: valor_firmado - description: > - Valor total originalmente acordado no Plano de Ação como meta de transferência de recursos. - - name: orcamento_recebido - description: > - Total de créditos orçamentários efetivamente recebidos por meio de Notas de Crédito. - - name: orcamento_devolvido - description: > - Total de créditos orçamentários devolvidos, identificado por eventos contábeis específicos (ex.: 300301, 300307). - - name: empenhado - description: > - Soma dos valores empenhados, ou seja, das despesas formalizadas no orçamento, excluindo anulações. - - name: empenho_anulado - description: > - Total de valores de empenhos anulados, ou seja, revertidos após sua emissão. - - name: despesas_pagas_exercicio - description: > - Total de despesas pagas no exercício corrente. - - name: despesas_pagas_rap - description: > - Total de despesas pagas com recursos de Restos a Pagar. - - name: restos_a_pagar - description: > - Valor total inscrito como Restos a Pagar, ou seja, despesas empenhadas e não pagas até o fim do exercício. - - name: despesas_liquidada - description: > - Soma das despesas liquidadas, indicando bens ou serviços efetivamente entregues. - - name: financeiro_recebido - description: > - Total de recursos financeiros recebidos via Programação Financeira (TED), considerando apenas ações classificadas como 'TRANSFERENCIA'. - - name: financeiro_devolvido - description: > - Total de recursos financeiros devolvidos, com ações classificadas como 'DEVOLUCAO'. - - name: financeiro_cancelado - description: > - Valor total de cancelamentos financeiros identificados na programação, com ação 'CANCELAMENTO'. - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) mais recente de ingestão dos dados das tabelas fonte utilizadas neste modelo. - diff --git a/dbt/ipea/models/ted_dbt/gold/ted_resumo_orcamentario.sql b/dbt/ipea/models/ted_dbt/gold/ted_resumo_orcamentario.sql deleted file mode 100644 index afab4b90..00000000 --- a/dbt/ipea/models/ted_dbt/gold/ted_resumo_orcamentario.sql +++ /dev/null @@ -1,116 +0,0 @@ --- Armazenando apenas os valores independentes das tabelas --- valores calculados serão computados no dashboard -with - - -- Valor firmado - valor_firmado_tb as ( - select - id_plano_acao as plano_acao, - vl_total_plano_acao as valor_firmado, - sigla_unidade_descentralizada, - ted_beneficiario_emitente, - dt_ingest as dt_ingest_vf - from {{ ref("planos_acao") }} - ), - - -- Orçamento recebido - -- Orçamento devolvido - valores_orcamentos_tb as ( - select - plano_acao, - num_transf, - sum( - case when nc_evento not in ('300301', '300307') then nc_valor else 0 end - ) as orcamento_recebido, - sum( - case when nc_evento in ('300301', '300307') then nc_valor else 0 end - ) as orcamento_devolvido, - max(dt_ingest) as dt_ingest_vo - from {{ ref("nc_plano_acao") }} - where ptres not in ('-9') - group by plano_acao, num_transf - ), - -- Destaque orçamentario = Orçamento recebido - Orçamento devolvido - -- Destaque a receber = Valor firmado - Destaque orçamentario - -- Empenhado - -- Empenho anulado - -- Utilizado/pago - valores_empenhados_tb as ( - select - plano_acao, - num_transf, - sum( - case when despesas_empenhadas > 0 then despesas_empenhadas else 0 end - ) as empenhado, - sum( - case when despesas_empenhadas < 0 then - despesas_empenhadas else 0 end - ) as empenho_anulado, - sum(despesas_pagas) as despesas_pagas_exercicio, - sum(restos_a_pagar_pagos) as despesas_pagas_rap, - sum(restos_a_pagar_inscritos) as restos_a_pagar, - sum(despesas_liquidadas) as despesas_liquidada, - max(dt_ingest) as dt_ingest_ve - from {{ ref("empenhos_plano_acao") }} - group by plano_acao, num_transf - ), - - -- Saldo empenho = Empenhado - Empenho anulado - Utilizado/pago - -- Financeiro recebido - -- Financeiro devolvido - -- Utilizado/pago - valores_financeiro_tb as ( - select - plano_acao, - num_transf, - sum( - case when pf_acao = 'TRANSFERENCIA' then pf_valor_linha else 0 end - ) as financeiro_recebido, - sum( - case when pf_acao = 'DEVOLUCAO' then pf_valor_linha else 0 end - ) as financeiro_devolvido, - sum( - case when pf_acao = 'CANCELAMENTO' then pf_valor_linha else 0 end - ) as financeiro_cancelado, - max(dt_ingest) as dt_ingest_vfin - from {{ ref("pf_plano_acao") }} - group by plano_acao, num_transf - ), - -- Saldo financeiro = Financeiro recebido - Financeiro devolvido - Utilizado/pago - -- Financeiro a receber = Valor firmado - Financeiro recebido + Financeiro devolvido - join_parcial as ( - select - *, - greatest(vo.dt_ingest_vo, ve.dt_ingest_ve, vfin.dt_ingest_vfin) as dt_ingest_jp - from valores_orcamentos_tb vo - full join valores_empenhados_tb ve using (plano_acao, num_transf) - full join valores_financeiro_tb vfin using (plano_acao, num_transf) - - ) --- Final -select - plano_acao, - num_transf, - sigla_unidade_descentralizada, - case - when ted_beneficiario_emitente = 'beneficiario' - then 'beneficiario' - when ted_beneficiario_emitente = 'emitente' - then 'emitente' - else 'nao_indicado' - end as ted_beneficiario_emitente, - valor_firmado, - orcamento_recebido, - orcamento_devolvido, - empenhado, - empenho_anulado, - despesas_pagas_exercicio, - despesas_pagas_rap, - restos_a_pagar, - despesas_liquidada, - financeiro_recebido, - financeiro_devolvido, - financeiro_cancelado, - greatest(vf.dt_ingest_vf, jp.dt_ingest_jp) as dt_ingest -from valor_firmado_tb vf -full join join_parcial jp using (plano_acao) -where (plano_acao is not null) or (num_transf is not null) diff --git a/dbt/ipea/models/ted_dbt/silver/empenhos_plano_acao.sql b/dbt/ipea/models/ted_dbt/silver/empenhos_plano_acao.sql deleted file mode 100644 index cfaff6ab..00000000 --- a/dbt/ipea/models/ted_dbt/silver/empenhos_plano_acao.sql +++ /dev/null @@ -1,35 +0,0 @@ -with - empenhos_ids as ( - select - *, - -- Uma série de extrações que servirão de identificadores - right(ne_ccor, 12) as ne, - replace( - ( - regexp_match( - ne_ccor_descricao, - '(FERENCIA|NUMERO|Nº|TED|CRICAO|TRANSF.|CAO|TRANSFERENCIA )(\s|^|-|)([0-9]{6}|1\w{5}|[0-9]{3}\.[0-9]{3})(\s|$|\.|,|-|\/)' - ) - )[3], - '.', - '' - ) as num_transf, - {{ target.schema }}.format_nc( - regexp_substr(ne_ccor_descricao, '([0-9]{4}NC[0-9]+)') - ) as nc - from {{ ref("empenhos_tesouro") }} - ), - empenhos_filtrados as ( - select * from empenhos_ids where (nc != '') or (num_transf is not null) - ), - planos_de_acao as ( - select * from {{ ref("num_transf_n_plano_acao") }} where plano_acao is not null - ), - result_table as ( - select distinct * - from empenhos_filtrados - left join planos_de_acao using (num_transf) - ) -- - -select * -from result_table diff --git a/dbt/ipea/models/ted_dbt/silver/nc_plano_acao.sql b/dbt/ipea/models/ted_dbt/silver/nc_plano_acao.sql deleted file mode 100644 index bcf2e990..00000000 --- a/dbt/ipea/models/ted_dbt/silver/nc_plano_acao.sql +++ /dev/null @@ -1,37 +0,0 @@ -with - - raw_data as (select * from {{ ref("nc_tesouro") }} nt where nc_transferencia != '-8'), - - planos_de_acao as ( - select distinct * - from {{ ref("num_transf_n_plano_acao") }} - where plano_acao is not null - ), - - result_table as ( - select - pda.plano_acao, - emissao_dia, - nc_transferencia as num_transf, - right(nc, 12) as nc, - nc_fonte_recursos, - ptres, - left(nc, 6) as ug_emitente, - nc_natureza_despesa, - nc_evento, - nc_evento_descr, - -- aplica o sinal correto a depender do tipo de evento - case - when nc_evento in ('300302', '300308', '300311', '300083') - then (-1) * nc_valor_linha - else nc_valor_linha - end as nc_valor, - rd.dt_ingest - from raw_data rd - left join planos_de_acao pda on rd.nc_transferencia = pda.num_transf - ) - --- -select * -from result_table -order by 1, 2 diff --git a/dbt/ipea/models/ted_dbt/silver/pf_plano_acao.sql b/dbt/ipea/models/ted_dbt/silver/pf_plano_acao.sql deleted file mode 100644 index dd877ade..00000000 --- a/dbt/ipea/models/ted_dbt/silver/pf_plano_acao.sql +++ /dev/null @@ -1,74 +0,0 @@ -with - - programacoes_financeira as ( - select - pf, - pf_inscricao as num_transf, - emissao_mes, - emissao_dia, - ug_emitente, - ug_favorecido, - pf_evento, - pf_evento_descricao, - substring(pf_acao_descricao, '(\w+) ') as pf_acao, - pf_valor_linha, - dt_ingest as dt_ingest_pf - from {{ ref("pf_tesouro") }} - ), - - pf_transfere_gov as ( - select - tx_numero_programacao as pf, - ug_emitente_programacao as ug_emitente, - id_plano_acao as plano_acao, - (dt_ingest || '-03:00')::timestamptz as dt_ingest_tg - from {{ source("transfere_gov", "programacao_financeira") }} -- raw - ), - - joined_by_transfere_gov as ( - select - pf, - num_transf, - emissao_mes, - emissao_dia, - ug_emitente, - ug_favorecido, - pf_evento, - pf_evento_descricao, - pf_acao, - pf_valor_linha, - t.plano_acao, - greatest(pf.dt_ingest_pf, t.dt_ingest_tg) as dt_ingest - from programacoes_financeira pf - inner join pf_transfere_gov t using (pf, ug_emitente) - ), - - joined_by_num_transf as ( - select - pf.pf, - pf.num_transf, - pf.emissao_mes, - pf.emissao_dia, - pf.ug_emitente, - pf.ug_favorecido, - pf.pf_evento, - pf.pf_evento_descricao, - pf.pf_acao, - pf.pf_valor_linha, - v.plano_acao, - pf.dt_ingest_pf as dt_ingest - from programacoes_financeira pf - inner join {{ ref("num_transf_n_plano_acao") }} v using (num_transf) - -- Exclui registros que já existem em joined_by_transfere_gov - where not exists ( - select 1 - from pf_transfere_gov t - where t.pf = pf.pf and t.ug_emitente = pf.ug_emitente - ) - ) - -select * -from joined_by_transfere_gov -union all -select * -from joined_by_num_transf \ No newline at end of file diff --git a/dbt/ipea/models/ted_dbt/silver/schema.yml b/dbt/ipea/models/ted_dbt/silver/schema.yml deleted file mode 100644 index 55b0523b..00000000 --- a/dbt/ipea/models/ted_dbt/silver/schema.yml +++ /dev/null @@ -1,125 +0,0 @@ -version: 2 - -models: - - - name: empenhos_plano_acao - description: > - Esta tabela estabelece a relação entre os empenhos registrados no SIAFI e os respectivos Planos de Ação, - permitindo o rastreamento das despesas públicas desde a origem do crédito até sua execução. - meta: - tags: - - silver - columns: - - name: ne - description: > - Número da Nota de Empenho, extraído dos 12 últimos dígitos do campo `ne_ccor`, representando o identificador do empenho no SIAFI. - - name: num_transf - description: > - Número da transferência identificado na descrição da nota de empenho (`ne_ccor_descricao`), utilizado para vincular o empenho ao Plano de Ação correspondente. - - name: nc - description: > - Código da Nota de Crédito associado ao empenho, extraído da descrição da nota de empenho e formatado conforme padrão estabelecido. - - name: plano_acao - description: > - Identificador do Plano de Ação relacionado ao empenho, obtido a partir da correspondência com o número de transferência (`num_transf`). - - name: ne_ccor - description: > - Campo original contendo o código completo da Nota de Empenho, utilizado como base para extração de identificadores. - - name: ne_ccor_descricao - description: > - Descrição textual da Nota de Empenho, de onde são extraídos os números de transferência e códigos de nota de crédito para associação com os Planos de Ação. - - name: demais_colunas - description: > - Outras colunas provenientes da tabela `empenhos_tesouro`, contendo informações adicionais sobre os empenhos, como data de emissão, valor, unidade gestora, entre outras. - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) mais recente de ingestão dos dados das tabelas fonte utilizadas neste modelo. - - - name: nc_plano_acao - description: > - Esta tabela estabelece a relação entre as Notas de Crédito registradas no SIAFI e os respectivos Planos de Ação, - permitindo o rastreamento das movimentações financeiras desde a origem do crédito até sua aplicação. - meta: - tags: - - silver - columns: - - name: plano_acao - description: > - Identificador do Plano de Ação relacionado à Nota de Crédito, obtido a partir da correspondência com o número de transferência (`nc_transferencia`). - - name: emissao_dia - description: > - Dia de emissão da Nota de Crédito. - - name: num_transf - description: > - Número da transferência associado à Nota de Crédito, utilizado para vincular a movimentação financeira ao Plano de Ação correspondente. - - name: nc - description: > - Código da Nota de Crédito, extraído dos 12 últimos dígitos do campo `nc`, representando o identificador da nota no SIAFI. - - name: nc_fonte_recursos - description: > - Código da fonte de recursos associada à Nota de Crédito, indicando a origem dos recursos utilizados. - - name: ptres - description: > - Código do Plano Interno de Trabalho (PTRES) vinculado à Nota de Crédito, representando a ação orçamentária correspondente. - - name: ug_emitente - description: > - Código da Unidade Gestora emitente da Nota de Crédito, extraído dos 6 primeiros dígitos do campo `nc`. - - name: nc_natureza_despesa - description: > - Código da natureza da despesa associada à Nota de Crédito, conforme classificação orçamentária. - - name: nc_evento - description: > - Código do evento contábil associado à Nota de Crédito, representando a natureza da transação. - - name: nc_evento_descr - description: > - Descrição do evento contábil vinculado à Nota de Crédito. - - name: nc_valor - description: > - Valor monetário da Nota de Crédito, ajustado conforme o tipo de evento contábil. - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) mais recente de ingestão dos dados das tabelas fonte utilizadas neste modelo. - - - name: pf_plano_acao - description: > - Esta tabela consolida as programações financeiras executadas no âmbito do SIAFI que estão relacionadas a Planos de Ação. - meta: - tags: - - silver - columns: - - name: pf - description: > - Número identificador da Programação Financeira, conforme registrado no SIAFI. - - name: num_transf - description: > - Número da transferência extraído do campo `pf_inscricao`, utilizado como chave alternativa para vinculação com Planos de Ação. - - name: emissao_mes - description: > - Mês da emissão da Programação Financeira, no formato numérico (1 a 12). - - name: emissao_dia - description: > - Dia da emissão da Programação Financeira, no formato numérico (1 a 31). - - name: ug_emitente - description: > - Código da Unidade Gestora responsável pela emissão da Programação Financeira. - - name: ug_favorecido - description: > - Código da Unidade Gestora favorecida pela Programação Financeira. - - name: pf_evento - description: > - Código do evento contábil associado à Programação Financeira, que descreve o tipo de movimentação registrada. - - name: pf_evento_descricao - description: > - Descrição do evento contábil da Programação Financeira, fornecendo contexto adicional sobre o tipo de operação realizada. - - name: pf_acao - description: > - Código da ação orçamentária extraído da descrição da programação financeira, representando a finalidade da despesa. - - name: pf_valor_linha - description: > - Valor programado para execução financeira, referente à linha específica da Programação Financeira. - - name: plano_acao - description: > - Identificador do Plano de Ação associado à Programação Financeira, determinado por correspondência direta com o sistema TransfereGov ou via número de transferência. - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) mais recente de ingestão dos dados das tabelas fonte utilizadas neste modelo. diff --git a/dbt/ipea/models/ted_dbt/views/num_transf_n_plano_acao.sql b/dbt/ipea/models/ted_dbt/views/num_transf_n_plano_acao.sql deleted file mode 100644 index b413f619..00000000 --- a/dbt/ipea/models/ted_dbt/views/num_transf_n_plano_acao.sql +++ /dev/null @@ -1,36 +0,0 @@ -{{ config(materialized="view") }} - -with - - nc_transfere_gov as ( - select distinct id_plano_acao, tx_numero_nota as nc, ndc.cd_ug_emitente_nota as ug - from {{ source("transfere_gov", "notas_de_credito") }} ndc - where ndc.tx_numero_nota is not null - ), - - nc_siafi as ( - select distinct - left(nc, 6) as ug, right(nc, 12) as nc, nt.nc_transferencia as num_transf - from {{ source("siafi", "nc_tesouro") }} nt - where nc_transferencia != '-8' - ), - - joined as ( - select distinct num_transf, id_plano_acao as plano_acao - from nc_siafi - left join nc_transfere_gov using (nc, ug) - ), - - ranked as ( - select - *, - row_number() over ( - partition by num_transf - order by case when plano_acao is not null then 1 else 2 end - ) as rn - from joined - ) - -select num_transf, plano_acao -from ranked -where rn = 1 diff --git a/dbt/ipea/models/ted_dbt/views/schema.yml b/dbt/ipea/models/ted_dbt/views/schema.yml deleted file mode 100644 index 3ad69e0b..00000000 --- a/dbt/ipea/models/ted_dbt/views/schema.yml +++ /dev/null @@ -1,16 +0,0 @@ -version: 2 - -models: - - - name: num_transf_n_plano_acao - description: > - View responsável por mapear o número de transferência (`num_transf`) ao respectivo Plano de Ação (`plano_acao`). - Utiliza dados de Notas de Crédito do TransfereGov e do SIAFI para realizar o cruzamento entre diferentes sistemas. - columns: - - name: num_transf - description: > - Número da transferência financeira obtido a partir dos registros do SIAFI (nota de crédito). Serve como chave para integrar informações entre diferentes fontes, como notas de crédito, programações financeiras e empenhos. - - name: plano_acao - description: > - Identificador único do Plano de Ação, conforme registrado no TransfereGov. É atribuído ao `num_transf` com base no cruzamento entre a nota de crédito (NC) e a unidade gestora emitente (UG). - diff --git a/dbt/ipea/seeds/estados_brasil.csv b/dbt/ipea/seeds/estados_brasil.csv deleted file mode 100644 index eaa791fd..00000000 --- a/dbt/ipea/seeds/estados_brasil.csv +++ /dev/null @@ -1,28 +0,0 @@ -sigla_uf,nome_uf -AC,ACRE -AL,ALAGOAS -AP,AMAPÁ -AM,AMAZONAS -BA,BAHIA -CE,CEARÁ -DF,DISTRITO FEDERAL -ES,ESPÍRITO SANTO -GO,GOIÁS -MA,MARANHÃO -MT,MATO GROSSO -MS,MATO GROSSO DO SUL -MG,MINAS GERAIS -PA,PARÁ -PB,PARAÍBA -PR,PARANÁ -PE,PERNAMBUCO -PI,PIAUÍ -RJ,RIO DE JANEIRO -RN,RIO GRANDE DO NORTE -RS,RIO GRANDE DO SUL -RO,RONDÔNIA -RR,RORAIMA -SC,SANTA CATARINA -SP,SÃO PAULO -SE,SERGIPE -TO,TOCANTINS diff --git a/dbt/ipea/snapshots/tables_snapshot.yml b/dbt/ipea/snapshots/tables_snapshot.yml deleted file mode 100644 index 84d36234..00000000 --- a/dbt/ipea/snapshots/tables_snapshot.yml +++ /dev/null @@ -1,36 +0,0 @@ -snapshots: - - name: contratos_snapshot - relation: ref('contratos') - config: - schema: snapshots - database: analytics - unique_key: id - strategy: check - check_cols: [situacao, num_parcelas, valor_parcela, valor_global, valor_acumulado] - - - name: faturas_snapshot - relation: ref('faturas') - config: - schema: snapshots - database: analytics - unique_key: [id, id_empenho] - strategy: check - check_cols: [situacao, valor, juros, multa, glosa] - - - name: empenhos_snapshot - relation: ref('empenhos') - config: - schema: snapshots - database: analytics - unique_key: [id, contrato_id] - strategy: check - check_cols: [empenhado, aliquidar, liquidado, pago, rpinscrito, rpaliquidar, rpliquidado, rppago] - - - name: cronogramas_snapshot - relation: ref('cronogramas') - config: - schema: snapshots - database: analytics - unique_key: id - strategy: check - check_cols: [valor, retroativo, observacao] \ No newline at end of file diff --git a/dbt/mir/dbt_project.yml b/dbt/minc/dbt_project.yml old mode 100755 new mode 100644 similarity index 50% rename from dbt/mir/dbt_project.yml rename to dbt/minc/dbt_project.yml index 9fccdb95..e7969b73 --- a/dbt/mir/dbt_project.yml +++ b/dbt/minc/dbt_project.yml @@ -1,15 +1,16 @@ -name: 'mir' +name: "minc" -version: 1.0.0 +version: "1.0.0" config-version: 2 -profile: mir +profile: "minc" model-paths: ["models"] analysis-paths: ["analyses"] -seed-paths: ["seeds"] test-paths: ["tests"] +seed-paths: ["seeds"] macro-paths: ["macros"] +snapshot-paths: ["snapshots"] clean-targets: - "target" @@ -17,21 +18,8 @@ clean-targets: - "logs" models: - mir: + minc: +database: analytics metadata: +materialized: incremental +schema: metadata - emendas_dbt: - +materialized: table - +schema: emendas - dados_abertos_dbt: - +materialized: table - +schema: dados_abertos - empenhos_ted_dbt: - +materialized: table - +schema: siafi_dbt - - -on-run-start: - - '{{create_udfs()}}' \ No newline at end of file diff --git a/dbt/minc/models/metadata/models_metadata.sql b/dbt/minc/models/metadata/models_metadata.sql new file mode 100644 index 00000000..46d5400b --- /dev/null +++ b/dbt/minc/models/metadata/models_metadata.sql @@ -0,0 +1,51 @@ +{{ + config( + materialized="incremental", + unique_key=["schema_name", "table_name"], + on_schema_change="sync_all_columns", + ) +}} + +with dbt_models as ( + {% set models_data = [] %} + + {% for node in graph.nodes.values() %} + {% if node.resource_type == "model" %} + {% do models_data.append({ + "schema_name": node.schema, + "table_name": node.name, + "database_name": node.database, + "materialization": node.config.materialized, + "description": node.description | default("") | replace("'", "''"), + }) %} + {% endif %} + {% endfor %} + + {% for model in models_data %} + select + '{{ model.schema_name }}' as schema_name, + '{{ model.table_name }}' as table_name, + '{{ model.database_name }}' as database_name, + '{{ model.materialization }}' as materialization, + '{{ model.description[:500] }}' as description, + ( + '{{ run_started_at }}'::timestamp + at time zone 'UTC' + at time zone 'America/Sao_Paulo' + ) as dt_transform, + '{{ invocation_id }}' as run_id + {% if not loop.last %} + union all + {% endif %} + {% endfor %} +) + +select + schema_name, + table_name, + database_name, + materialization, + description, + dt_transform, + run_id +from dbt_models diff --git a/dbt/minc/models/metadata/schema.yml b/dbt/minc/models/metadata/schema.yml new file mode 100644 index 00000000..1c8498cf --- /dev/null +++ b/dbt/minc/models/metadata/schema.yml @@ -0,0 +1,19 @@ +version: 2 + +models: + - name: models_metadata + description: Metadados dos modelos dbt do projeto MinC. + columns: + - name: schema_name + tests: + - not_null + - name: table_name + tests: + - not_null + - name: database_name + - name: materialization + - name: description + - name: dt_transform + tests: + - not_null + - name: run_id diff --git a/dbt/minc/models/sources.yml b/dbt/minc/models/sources.yml new file mode 100644 index 00000000..096cf1d5 --- /dev/null +++ b/dbt/minc/models/sources.yml @@ -0,0 +1,10 @@ +version: 2 + +sources: + - name: transferegov_fundo_a_fundo + schema: transferegov_fundo_a_fundo + tables: + - name: raw_programas + - name: raw_planos_acao + - name: relatorios_gestao + - name: anexos_relatorios diff --git a/dbt/ipea/profiles.yml b/dbt/minc/profiles.yml old mode 100755 new mode 100644 similarity index 85% rename from dbt/ipea/profiles.yml rename to dbt/minc/profiles.yml index 17f14e26..490f95d8 --- a/dbt/ipea/profiles.yml +++ b/dbt/minc/profiles.yml @@ -1,4 +1,4 @@ -ipea: +minc: target: prod outputs: prod: @@ -8,4 +8,4 @@ ipea: password: "{{ env_var('DB_DW_PASSWORD', 'postgres_dw') }}" port: "{{ env_var('DB_DW_PORT', '5432') | int }}" dbname: "{{ env_var('DB_DW_DBNAME', 'data_warehouse') }}" - schema: "{{ env_var('DB_DW_SCHEMA', 'ipea') }}" \ No newline at end of file + schema: "{{ env_var('DB_DW_SCHEMA', 'minc') }}" diff --git a/dbt/mir/.user.yml b/dbt/mir/.user.yml deleted file mode 100755 index 43198208..00000000 --- a/dbt/mir/.user.yml +++ /dev/null @@ -1 +0,0 @@ -id: d025f823-c5b2-49c6-b826-226fb25f1ad8 diff --git a/dbt/mir/descriptions.yml b/dbt/mir/descriptions.yml deleted file mode 100644 index e69de29b..00000000 diff --git a/dbt/mir/macros/create_udfs.sql b/dbt/mir/macros/create_udfs.sql deleted file mode 100644 index dd230cf5..00000000 --- a/dbt/mir/macros/create_udfs.sql +++ /dev/null @@ -1,10 +0,0 @@ -{% macro create_udfs() %} - -create schema if not exists {{ target.schema }}; - - {{ create_f_parse_dates() }} - ; - {{ create_f_format_nc() }} - ; - -{% endmacro %} diff --git a/dbt/mir/macros/data_quality/row_count_match.sql b/dbt/mir/macros/data_quality/row_count_match.sql deleted file mode 100644 index f248e30c..00000000 --- a/dbt/mir/macros/data_quality/row_count_match.sql +++ /dev/null @@ -1,14 +0,0 @@ -{% macro test_row_count_match(model, source_table, target_table) %} - with - source_count as (select count(*) as row_count from {{ source_table }}), - target_count as (select count(*) as row_count from {{ target_table }}), - comparison as ( - select - source_count.row_count as source_row_count, - target_count.row_count as target_row_count - from source_count, target_count - ) - select * - from comparison - where source_row_count != target_row_count -{% endmacro %} diff --git a/dbt/mir/macros/data_quality/verificacao_tipagem.sql b/dbt/mir/macros/data_quality/verificacao_tipagem.sql deleted file mode 100644 index 34c3d392..00000000 --- a/dbt/mir/macros/data_quality/verificacao_tipagem.sql +++ /dev/null @@ -1,25 +0,0 @@ -{% macro test_verificacao_tipagem(model, nome_tabela, nome_coluna, tipo_esperado) %} - with - column_info as ( - select - table_schema, - table_name, -- Nome real da coluna no information_schema - column_name, -- Nome real da coluna no information_schema - data_type - from information_schema.columns - where - table_schema || '.' || table_name = '{{ nome_tabela }}' - and column_name = '{{ nome_coluna }}' - ), - comparison as ( - select - '{{ nome_tabela }}' as nome_tabela, - '{{ nome_coluna }}' as nome_coluna, - '{{ tipo_esperado }}' as tipo_esperado, - data_type as actual_type - from column_info - ) - select * - from comparison - where actual_type != tipo_esperado -{% endmacro %} diff --git a/dbt/mir/macros/get_custom_schema.sql b/dbt/mir/macros/get_custom_schema.sql deleted file mode 100755 index 79444e9a..00000000 --- a/dbt/mir/macros/get_custom_schema.sql +++ /dev/null @@ -1,4 +0,0 @@ --- built-in schema generator -{% macro generate_schema_name(custom_schema_name, node) -%} - {{ generate_schema_name_for_env(custom_schema_name, node) }} -{%- endmacro %} diff --git a/dbt/mir/macros/metadata/generate_metadata.sql b/dbt/mir/macros/metadata/generate_metadata.sql deleted file mode 100644 index 8bfb115b..00000000 --- a/dbt/mir/macros/metadata/generate_metadata.sql +++ /dev/null @@ -1,46 +0,0 @@ -{% macro get_model_metadata() %} -{# - Esta macro retorna os metadados do modelo atual. - Pode ser usada em post-hooks para registrar metadados automaticamente. -#} - SELECT - '{{ this.schema }}' AS schema_name, - '{{ this.name }}' AS table_name, - '{{ this.database }}' AS database_name, - ('{{ run_started_at }}'::TIMESTAMP AT TIME ZONE 'UTC' AT TIME ZONE 'America/Sao_Paulo') AS dt_transform, - '{{ invocation_id }}' AS run_id -{% endmacro %} - - -{% macro register_model_metadata() %} -{# - Esta macro registra os metadados do modelo em uma tabela central. - Deve ser usada como post-hook nos modelos que deseja rastrear. - - Uso no dbt_project.yml: - models: - ipea: - +post-hook: - - "{{ register_model_metadata() }}" -#} - - INSERT INTO {{ target.database }}.metadata.models_metadata ( - schema_name, - table_name, - database_name, - dt_transform, - run_id - ) - VALUES ( - '{{ this.schema }}', - '{{ this.name }}', - '{{ this.database }}', - ('{{ run_started_at }}'::TIMESTAMP AT TIME ZONE 'UTC' AT TIME ZONE 'America/Sao_Paulo'), - '{{ invocation_id }}' - ) - ON CONFLICT (schema_name, table_name) - DO UPDATE SET - dt_transform = EXCLUDED.dt_transform, - run_id = EXCLUDED.run_id; - -{% endmacro %} diff --git a/dbt/mir/macros/parse_financial_value.sql b/dbt/mir/macros/parse_financial_value.sql deleted file mode 100644 index 437b673c..00000000 --- a/dbt/mir/macros/parse_financial_value.sql +++ /dev/null @@ -1,21 +0,0 @@ -{% macro parse_financial_value(column_name) %} - - case - when {{ column_name }} is null or trim({{ column_name }}) = '' - then 0.00::numeric(15, 2) - when {{ column_name }} like '%NaN%' - then 0.00::numeric(15, 2) - when {{ column_name }} like '(%' - then - regexp_replace( - replace(coalesce({{ column_name }}, '0'), '.', ''), - '(\()?(\d+),(\d+)(\))?', - '-\2.\3' - )::numeric(15, 2) - else - replace( - replace(coalesce({{ column_name }}, '0'), '.', ''), ',', '.' - )::numeric(15, 2) - end - -{% endmacro %} diff --git a/dbt/mir/macros/schema.yml b/dbt/mir/macros/schema.yml deleted file mode 100644 index 694f3b23..00000000 --- a/dbt/mir/macros/schema.yml +++ /dev/null @@ -1,24 +0,0 @@ - -version: 2 - -macros: - - name: create_udfs - description: > - Função que cria as UDFs necessárias para o funcionamento do projeto. - Essa função deve ser chamada no início de cada run para garantir que todas as UDFs estejam disponíveis. - - - name: generate_schema_name - description: > - Função que gera o nome do schema a ser utilizado no projeto. - A função dentro desta macro é built-in do dbt. - - ## UDFS - - name: create_f_parse_dates - description: > - Função que cria a UDF f_parse_dates, que é utilizada para converter texto no formato MÊS(texto)/ANO(numero) em datas. - arguments: - - name: in_text - type: text - description: > - Texto a ser convertido em data. - O texto deve estar no formato MÊS(texto)/ANO(numero). Ex.: FEV/2024 -> 2024-02-01 \ No newline at end of file diff --git a/dbt/mir/macros/udfs/f_format_nc.sql b/dbt/mir/macros/udfs/f_format_nc.sql deleted file mode 100644 index f7a06c86..00000000 --- a/dbt/mir/macros/udfs/f_format_nc.sql +++ /dev/null @@ -1,19 +0,0 @@ -{% macro create_f_format_nc() %} - create or replace function {{ target.schema }}.format_nc(in_text text) - returns text - as $$ - - with - - pre_process as ( - select left(in_text, 7) as prefix, - right(in_text, 4)::numeric as posfix - ) - - select concat(prefix, to_char(posfix, 'FM00000')) as result - from pre_process - - $$ - language sql - ; -{% endmacro %} diff --git a/dbt/mir/macros/udfs/f_parse_dates.sql b/dbt/mir/macros/udfs/f_parse_dates.sql deleted file mode 100644 index 3fd8693e..00000000 --- a/dbt/mir/macros/udfs/f_parse_dates.sql +++ /dev/null @@ -1,44 +0,0 @@ --- Essa fun -{% macro create_f_parse_dates() %} - - create or replace function {{ target.schema }}.parse_date(in_text text) - returns date - as - $$ - - with - - split_column as ( - select - split_part(in_text, '/', 1) as mes, - split_part(in_text, '/', 2) as ano - ), - - fixed_month as ( - select - ano, - case - when mes = 'JAN' then '01' - when mes = 'FEV' then '02' - when mes = 'MAR' then '03' - when mes = 'ABR' then '04' - when mes = 'MAI' then '05' - when mes = 'JUN' then '06' - when mes = 'JUL' then '07' - when mes = 'AGO' then '08' - when mes = 'SET' then '09' - when mes = 'OUT' then '10' - when mes = 'NOV' then '11' - when mes = 'DEZ' then '12' - else mes end as mes_num - from split_column - ) - - select - (to_date(ano::numeric - 1 || '-' || '12', 'YYYY-MM') + (mes_num || ' months')::interval)::date as result - from fixed_month - $$ - language sql - ; - -{% endmacro %} diff --git a/dbt/mir/models/dados_abertos_dbt/bronze/deputados.sql b/dbt/mir/models/dados_abertos_dbt/bronze/deputados.sql deleted file mode 100644 index c523a197..00000000 --- a/dbt/mir/models/dados_abertos_dbt/bronze/deputados.sql +++ /dev/null @@ -1,19 +0,0 @@ -{{ config(materialized="table") }} - -with - deputados_raw as ( - select - -- Conversão de tipos e formatação de colunas - id::integer as id, - nome::text as nome, - siglapartido::text as siglapartido, - siglauf::text as siglauf, - idlegislatura::integer as idlegislatura, - urlfoto::text as urlfoto, - email::text as email, - (dt_ingest || '-03:00')::timestamptz as dt_ingest - from {{ source("camara_deputados", "deputados") }} - ) - -select * -from deputados_raw diff --git a/dbt/mir/models/dados_abertos_dbt/bronze/schema.yml b/dbt/mir/models/dados_abertos_dbt/bronze/schema.yml deleted file mode 100644 index 13cbc8ba..00000000 --- a/dbt/mir/models/dados_abertos_dbt/bronze/schema.yml +++ /dev/null @@ -1,196 +0,0 @@ -version: 2 - -models: - # Dados Abertos DBT - - ## Bronze - - name: deputados - description: > - Tabela com informações básicas sobre deputados federais obtidas por meio da API de Dados Abertos da Câmara dos Deputados. - Contém dados cadastrais e institucionais como identificador, nome parlamentar, partido, unidade federativa, - legislatura e e-mail institucional. - Esta tabela representa a camada bronze do pipeline, aplicando padronização de tipos, - pequenas transformações e ajuste de fuso horário na data de ingestão. - Os dados são provenientes da fonte dados_abertos.deputados (camada raw) e - passam por conversão explícita de tipos para garantir consistência e rastreabilidade. - meta: - tags: - - bronze - columns: - - name: id - description: > - Identificador único do deputado na API da Câmara. - Utilizado como chave primária e referência para relacionamentos com outras tabelas. - - - name: nome - description: > - Nome parlamentar do deputado conforme registrado na Câmara dos Deputados. - - - name: siglapartido - description: > - Sigla do partido ao qual o deputado está filiado na legislatura informada. - - - name: siglauf - description: > - Sigla da Unidade Federativa (UF) que o deputado representa. - - - name: idlegislatura - description: > - Identificador numérico da legislatura à qual o deputado está vinculado. - - - name: urlfoto - description: > - URL da foto oficial do deputado disponibilizada pela Câmara dos Deputados. - - - name: email - description: > - Endereço de e-mail institucional do deputado na Câmara dos Deputados. - - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) em que os dados foram ingeridos da fonte original para a camada raw. - tests: - - verificacao_tipagem: - nome_tabela: 'deputados.deputados' - nome_coluna: 'id' - tipo_esperado: 'integer' - - - verificacao_tipagem: - nome_tabela: 'deputados.deputados' - nome_coluna: 'nome' - tipo_esperado: 'text' - - - verificacao_tipagem: - nome_tabela: 'deputados.deputados' - nome_coluna: 'siglapartido' - tipo_esperado: 'text' - - - verificacao_tipagem: - nome_tabela: 'deputados.deputados' - nome_coluna: 'siglauf' - tipo_esperado: 'text' - - - verificacao_tipagem: - nome_tabela: 'deputados.deputados' - nome_coluna: 'idlegislatura' - tipo_esperado: 'integer' - - - verificacao_tipagem: - nome_tabela: 'deputados' - nome_coluna: 'urlfoto' - tipo_esperado: 'text' - - - verificacao_tipagem: - nome_tabela: 'deputados.deputados' - nome_coluna: 'email' - tipo_esperado: 'text' - - - verificacao_tipagem: - nome_tabela: 'deputados.deputados' - nome_coluna: 'dt_ingest' - tipo_esperado: 'timestamp with time zone' - - - name: senadores - description: > - Tabela com informações básicas sobre senadores federais obtidas por meio da API de Dados Abertos do Senado Federal. - Contém dados cadastrais e institucionais como identificador, nome parlamentar, sexo, forma de tratamento, - partido, unidade federativa, URLs de foto e página, e e-mail institucional. - Esta tabela representa a camada bronze do pipeline, aplicando padronização de tipos, - pequenas transformações e ajuste de fuso horário na data de ingestão. - Os dados são provenientes da fonte senado_federal.senadores (camada raw) e - passam por conversão explícita de tipos para garantir consistência e rastreabilidade. - meta: - tags: - - bronze - columns: - - name: id - description: > - Identificador único do senador na API do Senado Federal. - Utilizado como chave primária e referência para relacionamentos com outras tabelas. - - - name: nome_parlamentar - description: > - Nome parlamentar do senador conforme registrado no Senado Federal. - - - name: sexo - description: > - Sexo do senador (Masculino ou Feminino). - - - name: forma_tratamento - description: > - Forma de tratamento do senador (ex: Senador, Senadora). - - - name: url_foto - description: > - URL da foto oficial do senador disponibilizada pelo Senado Federal. - - - name: url_pagina - description: > - URL da página de perfil do senador no portal do Senado Federal. - - - name: email - description: > - Endereço de e-mail institucional do senador no Senado Federal. - - - name: sigla_partido - description: > - Sigla do partido ao qual o senador está filiado. - - - name: uf - description: > - Sigla da Unidade Federativa (UF) que o senador representa. - - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) em que os dados foram ingeridos da fonte original para a camada raw. - - tests: - - verificacao_tipagem: - nome_tabela: 'senadores.senadores' - nome_coluna: 'id' - tipo_esperado: 'integer' - - - verificacao_tipagem: - nome_tabela: 'senadores.senadores' - nome_coluna: 'nome_parlamentar' - tipo_esperado: 'text' - - - verificacao_tipagem: - nome_tabela: 'senadores.senadores' - nome_coluna: 'sexo' - tipo_esperado: 'text' - - - verificacao_tipagem: - nome_tabela: 'senadores.senadores' - nome_coluna: 'forma_tratamento' - tipo_esperado: 'text' - - - verificacao_tipagem: - nome_tabela: 'senadores.senadores' - nome_coluna: 'url_foto' - tipo_esperado: 'text' - - - verificacao_tipagem: - nome_tabela: 'senadores.senadores' - nome_coluna: 'url_pagina' - tipo_esperado: 'text' - - - verificacao_tipagem: - nome_tabela: 'senadores.senadores' - nome_coluna: 'email' - tipo_esperado: 'text' - - - verificacao_tipagem: - nome_tabela: 'senadores.senadores' - nome_coluna: 'sigla_partido' - tipo_esperado: 'text' - - - verificacao_tipagem: - nome_tabela: 'senadores.senadores' - nome_coluna: 'uf' - tipo_esperado: 'text' - - - verificacao_tipagem: - nome_tabela: 'senadores.senadores' - nome_coluna: 'dt_ingest' - tipo_esperado: 'timestamp with time zone' diff --git a/dbt/mir/models/dados_abertos_dbt/bronze/senadores.sql b/dbt/mir/models/dados_abertos_dbt/bronze/senadores.sql deleted file mode 100644 index e6de70cc..00000000 --- a/dbt/mir/models/dados_abertos_dbt/bronze/senadores.sql +++ /dev/null @@ -1,20 +0,0 @@ -{{ config(materialized="table") }} - -with - senadores_raw as ( - select - id::integer as id, - nome_parlamentar::text as nome_parlamentar, - sexo::text as sexo, - forma_tratamento::text as forma_tratamento, - url_foto::text as url_foto, - url_pagina::text as url_pagina, - email::text as email, - sigla_partido::text as sigla_partido, - uf::text as uf, - (dt_ingest || '-03:00')::timestamptz as dt_ingest - from {{ source("senado_federal", "senadores") }} - ) - -select * -from senadores_raw diff --git a/dbt/mir/models/dados_abertos_dbt/silver/parlamentares.sql b/dbt/mir/models/dados_abertos_dbt/silver/parlamentares.sql deleted file mode 100644 index 49a49aa5..00000000 --- a/dbt/mir/models/dados_abertos_dbt/silver/parlamentares.sql +++ /dev/null @@ -1,77 +0,0 @@ -{{ config(materialized='table') }} - -WITH -bronze_deputados AS ( - SELECT * FROM {{ ref('deputados') }} -), - -bronze_senadores AS ( - SELECT * FROM {{ ref('senadores') }} -), - -sigla_map AS ( - SELECT - TRIM(UPPER(sigla_origem)) AS sigla_origem, - TRIM(UPPER(sigla_canonica)) AS sigla_canonica - FROM {{ ref('partidos_map') }} -), - -parlamentares_unificados AS ( - SELECT - id AS id_parlamentar, - TRIM(UPPER(nome)) AS chave_join_nome, - nome AS nome_parlamentar, - 'Deputado' AS cargo_parlamentar, - siglapartido AS sigla_partido, - siglauf AS uf_parlamentar, - urlfoto AS url_foto, - email - FROM bronze_deputados - - UNION ALL - - SELECT - id AS id_parlamentar, - TRIM(UPPER(nome_parlamentar)) AS chave_join_nome, - nome_parlamentar AS nome_parlamentar, - 'Senador' AS cargo_parlamentar, - sigla_partido AS sigla_partido, - uf AS uf_parlamentar, - url_foto AS url_foto, - email - FROM bronze_senadores -), - -parlamentares_padronizados AS ( - SELECT - p.*, - COALESCE(m.sigla_canonica, p.sigla_partido) AS sigla_partido_padronizada - FROM parlamentares_unificados p - LEFT JOIN sigla_map m - ON TRIM(UPPER(p.sigla_partido)) = m.sigla_origem -), - -partidos_logo AS ( - SELECT - TRIM(UPPER(sigla)) AS chave_join_sigla_partido, - logo_url - FROM {{ ref('partidos_logo') }} -) - -SELECT - p.id_parlamentar, - p.chave_join_nome, - p.nome_parlamentar, - p.cargo_parlamentar, - - p.sigla_partido_padronizada AS sigla_partido, - - p.uf_parlamentar, - p.url_foto, - p.email, - pl.logo_url AS url_logo_partido - -FROM parlamentares_padronizados p - -LEFT JOIN partidos_logo pl - ON TRIM(UPPER(p.sigla_partido_padronizada)) = pl.chave_join_sigla_partido \ No newline at end of file diff --git a/dbt/mir/models/dados_abertos_dbt/silver/schema.yml b/dbt/mir/models/dados_abertos_dbt/silver/schema.yml deleted file mode 100644 index 48e0d81f..00000000 --- a/dbt/mir/models/dados_abertos_dbt/silver/schema.yml +++ /dev/null @@ -1,80 +0,0 @@ -version: 2 - -models: - - name: parlamentares - description: > - Tabela silver que unifica informações de deputados e senadores - em uma visão única de parlamentares, incluindo partido, UF, - foto e logo do partido. - meta: - tags: - - silver - columns: - - name: id_parlamentar - description: > - Identificador único do parlamentar na base unificada - de deputados e senadores. - - name: chave_join_nome - description: > - Chave de junção padronizada (nome em caixa alta e trimado), - utilizada para relacionar parlamentares com outros modelos. - - name: nome_parlamentar - description: > - Nome do parlamentar conforme registrado na base de origem. - - name: cargo_parlamentar - description: > - Cargo do parlamentar (por exemplo, Deputado ou Senador). - - name: sigla_partido - description: > - Sigla do partido ao qual o parlamentar está filiado. - - name: uf_parlamentar - description: > - Sigla da Unidade Federativa (UF) que o parlamentar representa. - - name: url_foto - description: > - URL da foto oficial do parlamentar na base de origem. - - name: email - description: > - Endereço de e-mail institucional do parlamentar. - - name: url_logo_partido - description: > - URL da imagem (logo) do partido do parlamentar, - proveniente do seed partidos_logo. - tests: - - verificacao_tipagem: - nome_tabela: 'dados_abertos.parlamentares' - nome_coluna: 'id_parlamentar' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'dados_abertos.parlamentares' - nome_coluna: 'chave_join_nome' - tipo_esperado: 'text' - - verificacao_tipagem: - nome_tabela: 'dados_abertos.parlamentares' - nome_coluna: 'nome_parlamentar' - tipo_esperado: 'text' - - verificacao_tipagem: - nome_tabela: 'dados_abertos.parlamentares' - nome_coluna: 'cargo_parlamentar' - tipo_esperado: 'text' - - verificacao_tipagem: - nome_tabela: 'dados_abertos.parlamentares' - nome_coluna: 'sigla_partido' - tipo_esperado: 'text' - - verificacao_tipagem: - nome_tabela: 'dados_abertos.parlamentares' - nome_coluna: 'uf_parlamentar' - tipo_esperado: 'text' - - verificacao_tipagem: - nome_tabela: 'dados_abertos.parlamentares' - nome_coluna: 'url_foto' - tipo_esperado: 'text' - - verificacao_tipagem: - nome_tabela: 'dados_abertos.parlamentares' - nome_coluna: 'email' - tipo_esperado: 'text' - - verificacao_tipagem: - nome_tabela: 'dados_abertos.parlamentares' - nome_coluna: 'url_logo_partido' - tipo_esperado: 'text' - diff --git a/dbt/mir/models/emendas_dbt/bronze/documentos_habeis.sql b/dbt/mir/models/emendas_dbt/bronze/documentos_habeis.sql deleted file mode 100644 index f9acd06c..00000000 --- a/dbt/mir/models/emendas_dbt/bronze/documentos_habeis.sql +++ /dev/null @@ -1,33 +0,0 @@ -{{ config(materialized="table") }} - -with - documentos_habeis_raw as ( - select - id_dh::integer as id_dh, - id_empenho::integer as id_empenho, - numero_documento_habil::text as numero_documento_habil, - situacao_dh::integer as situacao_dh, - descricao_situacao_dh::text as descricao_situacao_dh, - tipo_documento_dh::text as tipo_documento_dh, - ug_emitente_dh::integer as ug_emitente_dh, - descricao_ug_emitente_dh::text as descricao_ug_emitente_dh, - data_vencimento_dh::date as data_vencimento_dh, - data_emissao_dh::date as data_emissao_dh, - ug_pagadora_dh::integer as ug_pagadora_dh, - descricao_ug_pagadora_dh::text as descricao_ug_pagadora_dh, - variacao_patrimonial_diminuta_dh::text as variacao_patrimonial_diminuta_dh, - passivo_transferencia_constitucional_legal_dh::text as passivo_transferencia_constitucional_legal_dh, - centro_custo_empenho::text as centro_custo_empenho, - codigo_siorg_empenho::integer as codigo_siorg_empenho, - mes_referencia_empenho::text as mes_referencia_empenho, - ano_referencia_empenho::integer as ano_referencia_empenho, - ug_beneficiada_dh::integer as ug_beneficiada_dh, - descricao_ug_beneficiada_dh::text as descricao_ug_beneficiada_dh, - valor_dh::numeric(15, 2) as valor_dh, - valor_rateio_dh::numeric(15, 2) as valor_rateio_dh, - (dt_ingest || '-03:00')::timestamptz as dt_ingest - from {{ source("transferegov_emendas", "documentos_habeis_especiais") }} - ) -- - -select * -from documentos_habeis_raw diff --git a/dbt/mir/models/emendas_dbt/bronze/empenhos_especiais.sql b/dbt/mir/models/emendas_dbt/bronze/empenhos_especiais.sql deleted file mode 100644 index 62afcacd..00000000 --- a/dbt/mir/models/emendas_dbt/bronze/empenhos_especiais.sql +++ /dev/null @@ -1,38 +0,0 @@ -{{ config(materialized="table") }} - -with - empenhos_raw as ( - select - id_empenho::integer as id_empenho, - id_minuta_empenho::text as id_minuta_empenho, - numero_empenho::text as numero_empenho, - situacao_empenho::integer as situacao_empenho, - descricao_situacao_empenho::text as descricao_situacao_empenho, - tipo_documento_empenho::integer as tipo_documento_empenho, - descricao_tipo_documento_empenho::text as descricao_tipo_documento_empenho, - status_processamento_empenho::text as status_processamento_empenho, - ug_responsavel_empenho::integer as ug_responsavel_empenho, - ug_emitente_empenho::integer as ug_emitente_empenho, - descricao_ug_emitente_empenho::text as descricao_ug_emitente_empenho, - fonte_recurso_empenho::text as fonte_recurso_empenho, - plano_interno_empenho::text as plano_interno_empenho, - ptres_empenho::numeric(15, 2) as ptres_empenho, -- verificar possibilidade de .0 - grupo_natureza_despesa_empenho::text as grupo_natureza_despesa_empenho, - natureza_despesa_empenho::text as natureza_despesa_empenho, - subitem_empenho::text as subitem_empenho, - categoria_despesa_empenho::text as categoria_despesa_empenho, - modalidade_despesa_empenho::integer as modalidade_despesa_empenho, - cnpj_beneficiario_empenho::text as cnpj_beneficiario_empenho, - nome_beneficiario_empenho::text as nome_beneficiario_empenho, - uf_beneficiario_empenho::text as uf_beneficiario_empenho, - numero_ro_empenho::text as numero_ro_empenho, - data_emissao_empenho::date as data_emissao_empenho, - prioridade_desbloqueio_empenho::integer as prioridade_desbloqueio_empenho, - valor_empenho::numeric(15, 2) as valor_empenho, - id_plano_acao::integer as id_plano_acao, - (dt_ingest || '-03:00')::timestamptz as dt_ingest - from {{ source("transferegov_emendas", "empenhos_especiais") }} - ) -- - -select * -from empenhos_raw diff --git a/dbt/mir/models/emendas_dbt/bronze/executor.sql b/dbt/mir/models/emendas_dbt/bronze/executor.sql deleted file mode 100644 index 5ed46bee..00000000 --- a/dbt/mir/models/emendas_dbt/bronze/executor.sql +++ /dev/null @@ -1,28 +0,0 @@ -{{ config(materialized="table") }} - -with - executor_especial_raw as ( - select - id_plano_acao::integer as id_plano_acao, - id_executor::integer as id_executor, - cnpj_executor::text as cnpj_executor, - nome_executor::text as nome_executor, - objeto_executor::text as objeto_executor, - vl_custeio_executor::numeric(15, 2) as valor_custeio_executor, - vl_investimento_executor::numeric(15, 2) as valor_investimento_executor, - ind_recursos_gerenciados_conta_especifica_executor::text as ind_recursos_gerenciados_conta_especifica_executor, - codigo_banco_executor::text as codigo_banco_executor, - nome_banco_executor::text as nome_banco_executor, - nullif(numero_agencia_executor, 'NaN')::numeric::integer as numero_agencia_executor, - dv_agencia_executor::text as dv_agencia_executor, - nome_agencia_executor::text as nome_agencia_executor, - numero_conta_executor::text as numero_conta_executor, - dv_conta_executor::text as dv_conta_executor, - codigo_situacao_dado_bancario_executor::integer as codigo_situacao_dado_bancario_executor, - descricao_situacao_dado_bancario_executor::text as descricao_situacao_dado_bancario_executor, - (dt_ingest || '-03:00')::timestamptz as dt_ingest - from {{ source("transferegov_emendas", "executor_especial") }} - ) - -select * -from executor_especial_raw \ No newline at end of file diff --git a/dbt/mir/models/emendas_dbt/bronze/finalidades.sql b/dbt/mir/models/emendas_dbt/bronze/finalidades.sql deleted file mode 100644 index d1c494f5..00000000 --- a/dbt/mir/models/emendas_dbt/bronze/finalidades.sql +++ /dev/null @@ -1,16 +0,0 @@ -{{ config(materialized="table") }} - -with - finalidade_especial_raw as ( - select - id_executor::integer as id_executor, - cd_area_politica_publica_tipo_pt::integer as cd_area_politica_publica_tipo_pt, - area_politica_publica_tipo_pt::text as area_politica_publica_tipo_pt, - cd_area_politica_publica_pt::integer as cd_area_politica_publica_pt, - area_politica_publica_pt::text as area_politica_publica_pt, - (dt_ingest || '-03:00')::timestamptz as dt_ingest - from {{ source("transferegov_emendas", "finalidades_especiais") }} - ) - -select * -from finalidade_especial_raw \ No newline at end of file diff --git a/dbt/mir/models/emendas_dbt/bronze/historico_pagamentos.sql b/dbt/mir/models/emendas_dbt/bronze/historico_pagamentos.sql deleted file mode 100644 index e10a98fd..00000000 --- a/dbt/mir/models/emendas_dbt/bronze/historico_pagamentos.sql +++ /dev/null @@ -1,16 +0,0 @@ -{{ config(materialized="table") }} - -with - historico_pagamentos_raw as ( - select - id_historico_op_ob::integer as id_historico_op_ob, - data_hora_historico_op::timestamp as data_hora_historico_op, - historico_situacao_op::integer as historico_situacao_op, - descricao_historico_situacao_op::text as descricao_historico_situacao_op, - id_op_ob::integer as id_op_ob, - (dt_ingest || '-03:00')::timestamptz as dt_ingest - from {{ source("transferegov_emendas", "historico_pagamentos_especiais") }} - ) -- - -select * -from historico_pagamentos_raw diff --git a/dbt/mir/models/emendas_dbt/bronze/metas.sql b/dbt/mir/models/emendas_dbt/bronze/metas.sql deleted file mode 100644 index 580b4df8..00000000 --- a/dbt/mir/models/emendas_dbt/bronze/metas.sql +++ /dev/null @@ -1,27 +0,0 @@ -{{ config(materialized="table") }} - -with - meta_especial_raw as ( - select - id_executor::integer as id_executor, - id_meta::integer as id_meta, - sequencial_meta::integer as sequencial_meta, - nome_meta::text as nome_meta, - desc_meta::text as desc_meta, - un_medida_meta::text as un_medida_meta, - qt_uniade_meta::numeric(15, 2) as qt_uniade_meta, - vl_custeio_emenda_especial_meta::numeric(15, 2) as valor_custeio_emenda_especial_meta, - vl_investimento_emenda_especial_meta::numeric(15, 2) as valor_investimento_emenda_especial_meta, - vl_custeio_recursos_proprios_meta::numeric(15, 2) as valor_custeio_recursos_proprios_meta, - vl_investimento_recursos_proprios_meta::numeric(15, 2) as valor_investimento_recursos_proprios_meta, - vl_custeio_rendimento_meta::numeric(15, 2) as valor_custeio_rendimento_meta, - vl_investimento_rendimento_meta::numeric(15, 2) as valor_investimento_rendimento_meta, - vl_custeio_doacao_meta::numeric(15, 2) as valor_custeio_doacao_meta, - vl_investimento_doacao_meta::numeric(15, 2) as valor_investimento_doacao_meta, - qt_meses_meta::integer as qt_meses_meta, - (dt_ingest || '-03:00')::timestamptz as dt_ingest - from {{ source("transferegov_emendas", "metas_especiais") }} - ) - -select * -from meta_especial_raw \ No newline at end of file diff --git a/dbt/mir/models/emendas_dbt/bronze/ordens_bancarias.sql b/dbt/mir/models/emendas_dbt/bronze/ordens_bancarias.sql deleted file mode 100644 index 8f0bd2c5..00000000 --- a/dbt/mir/models/emendas_dbt/bronze/ordens_bancarias.sql +++ /dev/null @@ -1,24 +0,0 @@ -{{ config(materialized="table") }} - -with - ordens_bancarias_raw as ( - select - id_op_ob::integer as id_op_ob, - data_emissao_op::date as data_emissao_op, - numero_ordem_pagamento::text as numero_ordem_pagamento, - vinculacao_op::integer as vinculacao_op, - situacao_op::integer as situacao_op, - descricao_situacao_op::text as descricao_situacao_op, - data_situacao_op::date as data_situacao_op, - data_emissao_ob::date as data_emissao_ob, - numero_ordem_bancaria::text as numero_ordem_bancaria, - numero_ordem_lancamento::text as numero_ordem_lancamento, - data_assinatura_ordenador_despesa_ob::date as data_assinatura_ordenador_despesa_ob, - data_assinatura_gestor_financeiro_ob::date as data_assinatura_gestor_financeiro_ob, - id_dh::integer as id_dh, - (dt_ingest || '-03:00')::timestamptz as dt_ingest - from {{ source("transferegov_emendas", "ordens_bancarias_especiais") }} - ) -- - -select * -from ordens_bancarias_raw diff --git a/dbt/mir/models/emendas_dbt/bronze/planos_acoes.sql b/dbt/mir/models/emendas_dbt/bronze/planos_acoes.sql deleted file mode 100644 index 74b72cef..00000000 --- a/dbt/mir/models/emendas_dbt/bronze/planos_acoes.sql +++ /dev/null @@ -1,38 +0,0 @@ -{{ config(materialized="table") }} - -with - planos_raw as ( - select - id_plano_acao::integer as id_plano_acao, - codigo_plano_acao::text as codigo_plano_acao, - ano_plano_acao::integer as ano_plano_acao, - modalidade_plano_acao::text as modalidade_plano_acao, - situacao_plano_acao::text as situacao_plano_acao, - cnpj_beneficiario_plano_acao::text as cnpj_beneficiario_plano_acao, - nome_beneficiario_plano_acao::text as nome_beneficiario_plano_acao, - uf_beneficiario_plano_acao::text as uf_beneficiario_plano_acao, - codigo_banco_plano_acao::text as codigo_banco_plano_acao, - NULLIF(codigo_situacao_dado_bancario_plano_acao::numeric, 'NaN'::numeric)::integer as codigo_situacao_dado_bancario_plano_acao, - nome_banco_plano_acao::text as nome_banco_plano_acao, - NULLIF(numero_agencia_plano_acao::numeric, 'NaN'::numeric)::integer as numero_agencia_plano_acao, - dv_agencia_plano_acao::text as dv_agencia_plano_acao, - NULLIF(numero_conta_plano_acao::numeric, 'NaN'::numeric)::integer as numero_conta_plano_acao, - dv_conta_plano_acao::text as dv_conta_plano_acao, - nome_parlamentar_emenda_plano_acao::text as nome_parlamentar_emenda_plano_acao, - ano_emenda_parlamentar_plano_acao::text as ano_emenda_parlamentar_plano_acao, - codigo_parlamentar_emenda_plano_acao::text as codigo_parlamentar_emenda_plano_acao, - sequencial_emenda_parlamentar_plano_acao::integer as sequencial_emenda_parlamentar_plano_acao, - numero_emenda_parlamentar_plano_acao::text as numero_emenda_parlamentar_plano_acao, - codigo_emenda_parlamentar_formatado_plano_acao::text as codigo_emenda_parlamentar_formatado_plano_acao, - codigo_descricao_areas_politicas_publicas_plano_acao::text as codigo_descricao_areas_politicas_publicas_plano_acao, - descricao_programacao_orcamentaria_plano_acao::text as descricao_programacao_orcamentaria_plano_acao, - motivo_impedimento_plano_acao::text as motivo_impedimento_plano_acao, - valor_custeio_plano_acao::numeric(15, 2) as valor_custeio_plano_acao, - valor_investimento_plano_acao::numeric(15, 2) as valor_investimento_plano_acao, - id_programa::integer as id_programa, - (dt_ingest || '-03:00')::timestamptz as dt_ingest - from {{ source("transferegov_emendas", "planos_acao_especiais") }} - ) -- - -select * -from planos_raw diff --git a/dbt/mir/models/emendas_dbt/bronze/planos_trabalho_especial.sql b/dbt/mir/models/emendas_dbt/bronze/planos_trabalho_especial.sql deleted file mode 100644 index 30a38a1b..00000000 --- a/dbt/mir/models/emendas_dbt/bronze/planos_trabalho_especial.sql +++ /dev/null @@ -1,22 +0,0 @@ -{{ config(materialized="table") }} - -with - planos_trabalho_raw as ( - select - id_plano_trabalho::integer as id_plano_trabalho, - situacao_plano_trabalho::text as situacao_plano_trabalho, - ind_orcamento_proprio_plano_trabalho::text as ind_orcamento_proprio_plano_trabalho, - data_inicio_execucao_plano_trabalho::timestamp as data_inicio_execucao_plano_trabalho, - data_fim_execucao_plano_trabalho::timestamp as data_fim_execucao_plano_trabalho, - prazo_execucao_meses_plano_trabalho::integer as prazo_execucao_meses_plano_trabalho, - id_plano_acao::integer as id_plano_acao, - classificacao_orcamentaria_pt::text as classificacao_orcamentaria_pt, - ind_justificativa_prorrogacao_atraso_pt::boolean as ind_justificativa_prorrogacao_atraso_pt, - ind_justificativa_prorrogacao_paralizacao_pt::boolean as ind_justificativa_prorrogacao_paralizacao_pt, - justificativa_prorrogacao_pt::text as justificativa_prorrogacao_pt, - (dt_ingest || '-03:00')::timestamptz as dt_ingest - from {{ source("transferegov_emendas", "plano_trabalho_especial") }} - ) -- - -select * -from planos_trabalho_raw diff --git a/dbt/mir/models/emendas_dbt/bronze/programas.sql b/dbt/mir/models/emendas_dbt/bronze/programas.sql deleted file mode 100644 index 15c0357c..00000000 --- a/dbt/mir/models/emendas_dbt/bronze/programas.sql +++ /dev/null @@ -1,30 +0,0 @@ -{{ config(materialized="table") }} - -with - programas_raw as ( - select - id_programa::integer as id_programa, - ano_programa::integer as ano_programa, - modalidade_programa::text as modalidade_programa, - codigo_programa::text as codigo_programa, - id_orgao_superior_programa:: integer as id_orgao_superior_programa, - sigla_orgao_programa::text as sigla_orgao_programa, - nome_orgao_programa::text as nome_orgao_programa, - id_unidade_gestora_programa::integer as id_unidade_gestora_programa, - documentos_origem_programa::text as documentos_origem_programa, - id_unidade_orcamentaria_responsavel_programa::integer as id_unidade_orcamentaria_responsavel_programa, - data_inicio_ciencia_programa::date as data_inicio_ciencia_programa, - data_fim_ciencia_programa::date as data_fim_ciencia_programa, - valor_necessidade_financeira_programa::numeric(15, 2) as valor_necessidade_financeira_programa, - valor_total_disponibilizado_programa::numeric(15, 2) as valor_total_disponibilizado_programa, - valor_impedido_programa::numeric(15, 2) as valor_impedido_programa, - valor_a_disponibilizar_programa::numeric(15, 2) as valor_a_disponibilizar_programa, - valor_documentos_habeis_gerados_programa::numeric(15, 2) as valor_documentos_habeis_gerados_programa, - valor_obs_geradas_programa::numeric(15, 2) as valor_obs_geradas_programa, - valor_disponibilidade_atual_programa::numeric(15, 2) as valor_disponibilidade_atual_programa, - (dt_ingest || '-03:00')::timestamptz as dt_ingest - from {{ source("transferegov_emendas", "programas_especiais") }} - ) -- - -select * -from programas_raw diff --git a/dbt/mir/models/emendas_dbt/bronze/relatorio_gestao.sql b/dbt/mir/models/emendas_dbt/bronze/relatorio_gestao.sql deleted file mode 100644 index b9714838..00000000 --- a/dbt/mir/models/emendas_dbt/bronze/relatorio_gestao.sql +++ /dev/null @@ -1,15 +0,0 @@ -{{ config(materialized="table") }} - -with - relatorio_gestao_raw as ( - select - id_relatorio_gestao::integer as id_relatorio_gestao, - situacao_relatorio_gestao::text as situacao_relatorio_gestao, - parecer_relatorio_gestao::text as parecer_relatorio_gestao, - id_plano_acao::integer as id_plano_acao, - (dt_ingest || '-03:00')::timestamptz as dt_ingest - from {{ source("transferegov_emendas", "relatorio_gestao_especial") }} - ) - -select * -from relatorio_gestao_raw \ No newline at end of file diff --git a/dbt/mir/models/emendas_dbt/bronze/relatorio_gestao_novo.sql b/dbt/mir/models/emendas_dbt/bronze/relatorio_gestao_novo.sql deleted file mode 100644 index 06d5cf48..00000000 --- a/dbt/mir/models/emendas_dbt/bronze/relatorio_gestao_novo.sql +++ /dev/null @@ -1,18 +0,0 @@ -{{ config(materialized="table") }} - -with - relatorio_gestao_novo_raw as ( - select - id_relatorio_gestao_novo::integer as id_relatorio_gestao_novo, - data_e_hora_relatorio_gestao_novo::timestamp as data_e_hora_relatorio_gestao_novo, - tipo_relatorio_gestao_novo::text as tipo_relatorio_gestao_novo, - valor_executado_relatorio_gestao_novo::numeric(15, 2) as valor_executado_relatorio_gestao_novo, - valor_pendente_relatorio_gestao_novo::numeric(15, 2) as valor_pendente_relatorio_gestao_novo, - situacao_relatorio_gestao_novo::text as situacao_relatorio_gestao_novo, - id_plano_acao::integer as id_plano_acao, - (dt_ingest || '-03:00')::timestamptz as dt_ingest - from {{ source("transferegov_emendas", "relatorios_gestao_novo_especial") }} - ) - -select * -from relatorio_gestao_novo_raw \ No newline at end of file diff --git a/dbt/mir/models/emendas_dbt/bronze/schema.yml b/dbt/mir/models/emendas_dbt/bronze/schema.yml deleted file mode 100644 index 7468e6c8..00000000 --- a/dbt/mir/models/emendas_dbt/bronze/schema.yml +++ /dev/null @@ -1,1132 +0,0 @@ -version: 2 - -models: - - # Emendas DBT - - ## Bronze - - name: programas - description: > - Tabela com informações sobre programas especiais do TransfereGov relacionados a emendas parlamentares. - Contém dados sobre a execução financeira dos programas, incluindo valores de necessidade financeira, - disponibilização, impedimentos e documentos hábeis gerados. - Os dados são extraídos da tabela programas_especiais do TransfereGov Emendas, com formatação adequada - de valores numéricos e datas. - meta: - tags: - - bronze - columns: - - name: id_programa - description: > - Identificador único do programa no TransfereGov. - - name: ano_programa - description: > - Ano de referência do programa. - - name: modalidade_programa - description: > - Modalidade do programa (ex: ESPECIAL). - - name: codigo_programa - description: > - Código identificador do programa no sistema. - - name: id_orgao_superior_programa - description: > - Identificador do órgão superior responsável pelo programa. - - name: sigla_orgao_programa - description: > - Sigla do órgão responsável pelo programa. - - name: nome_orgao_programa - description: > - Nome completo do órgão responsável pelo programa. - - name: id_unidade_gestora_programa - description: > - Identificador da unidade gestora responsável pelo programa. - - name: documentos_origem_programa - description: > - Documentos de origem associados ao programa. - - name: id_unidade_orcamentaria_responsavel_programa - description: > - Identificador da unidade orçamentária responsável pelo programa. - - name: data_inicio_ciencia_programa - description: > - Data de início de ciência do programa. - - name: data_fim_ciencia_programa - description: > - Data de fim de ciência do programa. - - name: valor_necessidade_financeira_programa - description: > - Valor da necessidade financeira do programa. - - name: valor_total_disponibilizado_programa - description: > - Valor total disponibilizado para o programa. - - name: valor_impedido_programa - description: > - Valor impedido do programa. - - name: valor_a_disponibilizar_programa - description: > - Valor ainda a ser disponibilizado para o programa. - - name: valor_documentos_habeis_gerados_programa - description: > - Valor dos documentos hábeis gerados para o programa. - - name: valor_obs_geradas_programa - description: > - Valor das ordens bancárias geradas para o programa. - - name: valor_disponibilidade_atual_programa - description: > - Valor da disponibilidade financeira atual do programa. - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) em que os dados foram ingeridos da fonte original para a camada raw. - tests: - - verificacao_tipagem: - nome_tabela: 'emendas.programas' - nome_coluna: 'id_programa' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.programas' - nome_coluna: 'ano_programa' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.programas' - nome_coluna: 'id_orgao_superior_programa' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.programas' - nome_coluna: 'id_unidade_gestora_programa' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.programas' - nome_coluna: 'id_unidade_orcamentaria_responsavel_programa' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.programas' - nome_coluna: 'data_inicio_ciencia_programa' - tipo_esperado: 'date' - - verificacao_tipagem: - nome_tabela: 'emendas.programas' - nome_coluna: 'data_fim_ciencia_programa' - tipo_esperado: 'date' - - verificacao_tipagem: - nome_tabela: 'emendas.programas' - nome_coluna: 'valor_necessidade_financeira_programa' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'emendas.programas' - nome_coluna: 'valor_total_disponibilizado_programa' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'emendas.programas' - nome_coluna: 'valor_impedido_programa' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'emendas.programas' - nome_coluna: 'valor_a_disponibilizar_programa' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'emendas.programas' - nome_coluna: 'valor_documentos_habeis_gerados_programa' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'emendas.programas' - nome_coluna: 'valor_obs_geradas_programa' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'emendas.programas' - nome_coluna: 'valor_disponibilidade_atual_programa' - tipo_esperado: 'numeric' - - - name: planos_acoes - description: > - Tabela com informações sobre os planos de ação especiais relacionados a emendas parlamentares do TransfereGov. - Contém dados sobre beneficiários, dados bancários, emendas parlamentares, classificação orçamentária, - impedimentos e valores de custeio e investimento. - Os dados são extraídos da tabela planos_acao_especiais do TransfereGov Emendas, com formatação adequada - de valores numéricos. - meta: - tags: - - bronze - columns: - - name: id_plano_acao - description: > - Identificador único do Plano de Ação (PA). - - name: codigo_plano_acao - description: > - Código do Programa concatenado com o ID do Plano de Ação. - - name: ano_plano_acao - description: > - Ano de criação do Plano de Ação. - - name: modalidade_plano_acao - description: > - Modalidade de Transferência do Plano de Ação. - - name: situacao_plano_acao - description: > - Situação do Plano de Ação. - - name: cnpj_beneficiario_plano_acao - description: > - CNPJ – Cadastro Nacional de Pessoa Jurídica do Beneficiário do Plano de Ação. - - name: nome_beneficiario_plano_acao - description: > - Nome do Beneficiário do Plano de Ação. - - name: uf_beneficiario_plano_acao - description: > - Sigla da Unidade de Federação do beneficiário. - - name: codigo_banco_plano_acao - description: > - Código do Banco do PA. - - name: codigo_situacao_dado_bancario_plano_acao - description: > - Código da Situação da Conta Corrente do PA. - - name: nome_banco_plano_acao - description: > - Nome do Banco do PA. - - name: numero_agencia_plano_acao - description: > - Número da Agência Bancária da Conta Corrente do PA. - - name: dv_agencia_plano_acao - description: > - Dígito Verificador da Agência Bancária da Conta Corrente do PA. - - name: numero_conta_plano_acao - description: > - Número da Conta Corrente do PA. - - name: dv_conta_plano_acao - description: > - Dígito Verificador da Conta Corrente do PA. - - name: nome_parlamentar_emenda_plano_acao - description: > - Nome do Parlamentar Autor da Emenda. - - name: ano_emenda_parlamentar_plano_acao - description: > - Ano da Emenda Parlamentar. - - name: codigo_parlamentar_emenda_plano_acao - description: > - Código do Parlamentar Autor da Emenda. - - name: sequencial_emenda_parlamentar_plano_acao - description: > - Sequencial da Emenda por Parlamentar no Ano. - - name: numero_emenda_parlamentar_plano_acao - description: > - Concatenação do Ano, Código e Sequencial do Parlamentar. - - name: codigo_emenda_parlamentar_formatado_plano_acao - description: > - Código Formatado da Emenda Parlamentar. - - name: codigo_descricao_areas_politicas_publicas_plano_acao - description: > - Concatenação dos Códigos e Descrições dos Tipos da Áreas das Políticas Públicas - com os Códigos e Descrições das Áreas das Políticas Públicas. - - name: descricao_programacao_orcamentaria_plano_acao - description: > - Concatenação das Programações Orçamentárias constantes da Lei Orçamentária do ente - beneficiado na qual o recurso será apropriado. - - name: motivo_impedimento_plano_acao - description: > - Motivo do Impedimento do Plano de Ação. - - name: valor_custeio_plano_acao - description: > - Valor Consolidado de Custeio das Emendas Parlamentares do Plano de Ação. - - name: valor_investimento_plano_acao - description: > - Valor Consolidado de Investimento das Emendas Parlamentares do Plano de Ação. - - name: id_programa - description: > - Identificador único do Programa associado ao Plano de Ação. - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) em que os dados foram ingeridos da fonte original para a camada raw. - tests: - - verificacao_tipagem: - nome_tabela: 'emendas.planos_acoes' - nome_coluna: 'id_plano_acao' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.planos_acoes' - nome_coluna: 'ano_plano_acao' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.planos_acoes' - nome_coluna: 'codigo_situacao_dado_bancario_plano_acao' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.planos_acoes' - nome_coluna: 'numero_agencia_plano_acao' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.planos_acoes' - nome_coluna: 'numero_conta_plano_acao' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.planos_acoes' - nome_coluna: 'sequencial_emenda_parlamentar_plano_acao' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.planos_acoes' - nome_coluna: 'valor_custeio_plano_acao' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'emendas.planos_acoes' - nome_coluna: 'valor_investimento_plano_acao' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'emendas.planos_acoes' - nome_coluna: 'id_programa' - tipo_esperado: 'integer' - - - name: empenhos_especiais - description: > - Tabela com informações sobre empenhos (Notas de Empenho) relacionados a emendas parlamentares do TransfereGov. - Contém dados sobre a execução orçamentária dos empenhos, incluindo valores, beneficiários, - classificação orçamentária e situação. - Os dados são extraídos da tabela empenhos_especiais do TransfereGov Emendas, com formatação adequada - de valores numéricos e datas. - meta: - tags: - - bronze - columns: - - name: id_empenho - description: > - Identificador único da Nota de Empenho (NE). - - name: id_minuta_empenho - description: > - Número da Minuta gerado para Nota de Empenho, utiliza o Número Interno e Ano de Emissão. - - name: numero_empenho - description: > - Número da Nota de Empenho gerada e enviada pelo SIAFI (Sistema Integrado de Administração Financeira). - - name: situacao_empenho - description: > - Código da situação da Nota de Empenho. - - name: descricao_situacao_empenho - description: > - Descrição da situação da Nota de Empenho. - - name: tipo_documento_empenho - description: > - Código do tipo da Nota de Empenho. - - name: descricao_tipo_documento_empenho - description: > - Descrição do tipo da Nota de Empenho. - - name: status_processamento_empenho - description: > - Indica o status do processamento em lote da Nota de Empenho. - - name: ug_responsavel_empenho - description: > - Código da Unidade Gestora Responsável da Nota de Empenho. - - name: ug_emitente_empenho - description: > - Código da Unidade Gestora Emitente da Nota de Empenho. - - name: descricao_ug_emitente_empenho - description: > - Nome da Unidade Gestora Emitente da Nota de Empenho. - - name: fonte_recurso_empenho - description: > - Fonte de Recurso da Nota de Empenho no SIAFI (Sistema Integrado de Administração Financeira). - - name: plano_interno_empenho - description: > - Instrumento de planejamento e de acompanhamento da ação planejada, usado como forma de detalhamento desta, - de uso exclusivo de cada Ministério/órgão. Código com até 11 posições alfa-numéricas. - - name: ptres_empenho - description: > - Número do Programa de Trabalho Resumido. - - name: grupo_natureza_despesa_empenho - description: > - Primeiro dígito do Código da Natureza de Despesa no SIAFI. - - name: natureza_despesa_empenho - description: > - Código da Natureza de Despesa no SIAFI (Sistema Integrado de Administração Financeira). - - name: subitem_empenho - description: > - Valor do Sub-item da Natureza de Despesa no SIAFI (Sistema Integrado de Administração Financeira). - - name: categoria_despesa_empenho - description: > - Código da Categoria de Despesa associada à Nota de Empenho. - - name: modalidade_despesa_empenho - description: > - Código da Modalidade de Despesa. - - name: cnpj_beneficiario_empenho - description: > - CNPJ do beneficiário da Nota de Empenho. - - name: nome_beneficiario_empenho - description: > - Nome do beneficiário da Nota de Empenho. - - name: uf_beneficiario_empenho - description: > - Sigla da Unidade da Federação do beneficiário. - - name: numero_ro_empenho - description: > - Número da lista gerado e enviado pelo SIAFI (Sistema Integrado de Administração Financeira). - - name: data_emissao_empenho - description: > - Data de envio ao SIAFI (Sistema Integrado de Administração Financeira), convertida para formato de data padrão. - - name: prioridade_desbloqueio_empenho - description: > - Indicador de prioridade no desbloqueio de recursos. - - name: valor_empenho - description: > - Valor total da Nota de Empenho, formatado como numérico. - - name: id_plano_acao - description: > - Identificador único do Plano de Ação (PA) relacionado ao empenho. - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) em que os dados foram ingeridos da fonte original para a camada raw. - tests: - - verificacao_tipagem: - nome_tabela: 'emendas.empenhos_emendas' - nome_coluna: 'id_empenho' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.empenhos_emendas' - nome_coluna: 'situacao_empenho' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.empenhos_emendas' - nome_coluna: 'tipo_documento_empenho' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.empenhos_emendas' - nome_coluna: 'ug_responsavel_empenho' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.empenhos_emendas' - nome_coluna: 'ug_emitente_empenho' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.empenhos_emendas' - nome_coluna: 'ptres_empenho' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.empenhos_emendas' - nome_coluna: 'modalidade_despesa_empenho' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.empenhos_emendas' - nome_coluna: 'data_emissao_empenho' - tipo_esperado: 'date' - - verificacao_tipagem: - nome_tabela: 'emendas.empenhos_emendas' - nome_coluna: 'prioridade_desbloqueio_empenho' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.empenhos_emendas' - nome_coluna: 'valor_empenho' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'emendas.empenhos_emendas' - nome_coluna: 'id_plano_acao' - tipo_esperado: 'integer' - - - name: ordens_bancarias - description: > - Tabela com informações sobre ordens de pagamento e ordens bancárias relacionadas a emendas parlamentares - do TransfereGov. Contém dados sobre a emissão, situação e assinaturas das ordens de pagamento e bancárias, - incluindo vinculação ao SIAFI e referência ao documento hábil de origem. - Os dados são extraídos da tabela ordem_pagamento_ordem_bancaria_especial do TransfereGov Emendas, - com formatação adequada de datas. - meta: - tags: - - bronze - columns: - - name: id_op_ob - description: > - Identificador único da Operação de Ordem Bancária. - - name: data_emissao_op - description: > - Data da emissão da Ordem de Pagamento. - - name: numero_ordem_pagamento - description: > - Número da Ordem de Pagamento, no formato AAAAOPNNNNNN (ex: "2020OP146800"). - - name: vinculacao_op - description: > - Código da vinculação da Ordem de Pagamento no SIAFI (Padrão: 405). - - name: situacao_op - description: > - Código da situação da Ordem de Pagamento/Bancária. - - name: descricao_situacao_op - description: > - Descrição da situação da Ordem de Pagamento/Bancária. - - name: data_situacao_op - description: > - Data da situação da Ordem de Pagamento/Bancária. - - name: data_emissao_ob - description: > - Data da emissão da Ordem Bancária no SIAFI. - - name: numero_ordem_bancaria - description: > - Número da Ordem Bancária, no formato AAAAOBNNNNNN (ex: "2020OB146800"). - - name: numero_ordem_lancamento - description: > - Número da Nota de Lançamento no sistema, no formato AAAANSNNNNNN (ex: "2020NS146800"). - - name: data_assinatura_ordenador_despesa_ob - description: > - Data de assinatura do Ordenador de Despesa. - - name: data_assinatura_gestor_financeiro_ob - description: > - Data de assinatura do Gestor Financeiro. - - name: id_dh - description: > - Identificador único do Documento Hábil (DH) vinculado à ordem bancária. - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) em que os dados foram ingeridos da fonte original para a camada raw. - tests: - - verificacao_tipagem: - nome_tabela: 'emendas.ordens_bancarias' - nome_coluna: 'id_op_ob' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.ordens_bancarias' - nome_coluna: 'data_emissao_op' - tipo_esperado: 'date' - - verificacao_tipagem: - nome_tabela: 'emendas.ordens_bancarias' - nome_coluna: 'vinculacao_op' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.ordens_bancarias' - nome_coluna: 'situacao_op' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.ordens_bancarias' - nome_coluna: 'data_situacao_op' - tipo_esperado: 'date' - - verificacao_tipagem: - nome_tabela: 'emendas.ordens_bancarias' - nome_coluna: 'data_emissao_ob' - tipo_esperado: 'date' - - verificacao_tipagem: - nome_tabela: 'emendas.ordens_bancarias' - nome_coluna: 'data_assinatura_ordenador_despesa_ob' - tipo_esperado: 'date' - - verificacao_tipagem: - nome_tabela: 'emendas.ordens_bancarias' - nome_coluna: 'data_assinatura_gestor_financeiro_ob' - tipo_esperado: 'date' - - verificacao_tipagem: - nome_tabela: 'emendas.ordens_bancarias' - nome_coluna: 'id_dh' - tipo_esperado: 'integer' - - - name: historico_pagamentos - description: > - Tabela com informações sobre o histórico de eventos das ordens de pagamento relacionadas a emendas - parlamentares do TransfereGov. Contém dados sobre os eventos (situações) ocorridos ao longo do ciclo - de vida de cada ordem de pagamento, incluindo data/hora da ocorrência e descrição do evento. - Os dados são extraídos da tabela historico_pagamento_especial do TransfereGov Emendas. - meta: - tags: - - bronze - columns: - - name: id_historico_op_ob - description: > - Identificador único do registro de histórico da ordem de pagamento/bancária. - - name: data_hora_historico_op - description: > - Data e hora da inserção ou atualização do registro, conforme hora do sistema. - - name: historico_situacao_op - description: > - Código do evento da Ordem de Pagamento. - - name: descricao_historico_situacao_op - description: > - Descrição do evento da Ordem de Pagamento. - - name: id_op_ob - description: > - Identificador único da Operação de Ordem Bancária associada ao histórico. - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) em que os dados foram ingeridos da fonte original para a camada raw. - tests: - - verificacao_tipagem: - nome_tabela: 'emendas.historico_pagamentos' - nome_coluna: 'id_historico_op_ob' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.historico_pagamentos' - nome_coluna: 'data_hora_historico_op' - tipo_esperado: 'timestamp without time zone' - - verificacao_tipagem: - nome_tabela: 'emendas.historico_pagamentos' - nome_coluna: 'historico_situacao_op' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.historico_pagamentos' - nome_coluna: 'id_op_ob' - tipo_esperado: 'integer' - - - name: planos_trabalho_especial - description: > - Tabela com informações sobre os planos de trabalho especiais relacionados a emendas parlamentares - do TransfereGov. Contém dados sobre o planejamento de execução, incluindo situação, prazos, - indicadores de orçamento próprio, classificação orçamentária e justificativas de prorrogação. - Os dados são extraídos da tabela plano_trabalho_especial do TransfereGov Emendas. - meta: - tags: - - bronze - columns: - - name: id_plano_trabalho - description: > - Identificador único do Planejamento. - - name: situacao_plano_trabalho - description: > - Identificador da situação do Planejamento. - - name: ind_orcamento_proprio_plano_trabalho - description: > - Indicador de que os recursos do Plano de Ação foram indicados no orçamento próprio do Beneficiário. - - name: data_inicio_execucao_plano_trabalho - description: > - Data de início da execução do Plano de Trabalho Especial. - - name: data_fim_execucao_plano_trabalho - description: > - Data prevista para o fim da execução do Plano de Trabalho Especial com base no prazo de execução. - - name: prazo_execucao_meses_plano_trabalho - description: > - Prazo de execução em meses. - - name: id_plano_acao - description: > - Identificador do Plano de Ação da Proposta. - - name: classificacao_orcamentaria_pt - description: > - Texto com classificação orçamentária da despesa informado quando indicado no orçamento próprio. - - name: ind_justificativa_prorrogacao_atraso_pt - description: > - Indica atraso na liberação dos recursos. - - name: ind_justificativa_prorrogacao_paralizacao_pt - description: > - Indica paralização da execução do objeto. - - name: justificativa_prorrogacao_pt - description: > - Detalhamento da justificativa da prorrogação de prazo. - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) em que os dados foram ingeridos da fonte original para a camada raw. - tests: - - verificacao_tipagem: - nome_tabela: 'emendas.planos_trabalho_especial' - nome_coluna: 'id_plano_trabalho' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.planos_trabalho_especial' - nome_coluna: 'data_inicio_execucao_plano_trabalho' - tipo_esperado: 'timestamp without time zone' - - verificacao_tipagem: - nome_tabela: 'emendas.planos_trabalho_especial' - nome_coluna: 'data_fim_execucao_plano_trabalho' - tipo_esperado: 'timestamp without time zone' - - verificacao_tipagem: - nome_tabela: 'emendas.planos_trabalho_especial' - nome_coluna: 'prazo_execucao_meses_plano_trabalho' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.planos_trabalho_especial' - nome_coluna: 'id_plano_acao' - tipo_esperado: 'integer' - - - name: documentos_habeis - description: > - Tabela com informações sobre documentos hábeis relacionados a emendas parlamentares do TransfereGov. - Contém dados sobre a emissão, situação, unidades gestoras envolvidas, valores e referências - orçamentárias dos documentos hábeis vinculados aos empenhos. - Os dados são extraídos da tabela documentos_habeis_especiais do TransfereGov Emendas, - com formatação adequada de valores numéricos e datas. - meta: - tags: - - bronze - columns: - - name: id_dh - description: > - Identificador único do Documento Hábil (DH). - - name: id_empenho - description: > - Identificador único da Nota de Empenho (NE) vinculada ao documento hábil. - - name: numero_documento_habil - description: > - Número do DH no formato YYYYTTNNNNNN (ex: "2020TF000001"). - - name: situacao_dh - description: > - Código da situação do Documento Hábil. - - name: descricao_situacao_dh - description: > - Descrição da situação do Documento Hábil. - - name: tipo_documento_dh - description: > - Código do tipo do Documento Hábil. - - name: ug_emitente_dh - description: > - Código da Unidade Gestora Emitente do Documento Hábil. - - name: descricao_ug_emitente_dh - description: > - Nome da Unidade Gestora Emitente do Documento Hábil. - - name: data_vencimento_dh - description: > - Data de vencimento do Documento Hábil. - - name: data_emissao_dh - description: > - Data de emissão do Documento Hábil. - - name: ug_pagadora_dh - description: > - Código da Unidade de Gestão Pagadora do Documento Hábil. - - name: descricao_ug_pagadora_dh - description: > - Nome da Unidade de Gestão Pagadora do Documento Hábil. - - name: variacao_patrimonial_diminuta_dh - description: > - Variação Patrimonial Diminutiva. - - name: passivo_transferencia_constitucional_legal_dh - description: > - Passivo de Transferência Legal ou Constitucional. - - name: centro_custo_empenho - description: > - Código do Centro de Custo. - - name: codigo_siorg_empenho - description: > - Código SIORG do Centro de Custo. - - name: mes_referencia_empenho - description: > - Mês de referência do Centro de Custo. - - name: ano_referencia_empenho - description: > - Ano de referência do Centro de Custo. - - name: ug_beneficiada_dh - description: > - Código da Unidade Gestora Beneficiada do Documento Hábil. - - name: descricao_ug_beneficiada_dh - description: > - Nome da Unidade Gestora Beneficiada do Documento Hábil. - - name: valor_dh - description: > - Valor do Documento Hábil. Se a Disponibilidade Financeira for menor que o valor do Empenho, - mais de um Documento Hábil pode ser criado. - - name: valor_rateio_dh - description: > - Valor do Rateio. - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) em que os dados foram ingeridos da fonte original para a camada raw. - tests: - - verificacao_tipagem: - nome_tabela: 'emendas.documentos_habeis' - nome_coluna: 'id_dh' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.documentos_habeis' - nome_coluna: 'id_empenho' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.documentos_habeis' - nome_coluna: 'situacao_dh' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.documentos_habeis' - nome_coluna: 'ug_emitente_dh' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.documentos_habeis' - nome_coluna: 'data_vencimento_dh' - tipo_esperado: 'date' - - verificacao_tipagem: - nome_tabela: 'emendas.documentos_habeis' - nome_coluna: 'data_emissao_dh' - tipo_esperado: 'date' - - verificacao_tipagem: - nome_tabela: 'emendas.documentos_habeis' - nome_coluna: 'ug_pagadora_dh' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.documentos_habeis' - nome_coluna: 'codigo_siorg_empenho' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.documentos_habeis' - nome_coluna: 'ano_referencia_empenho' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.documentos_habeis' - nome_coluna: 'ug_beneficiada_dh' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.documentos_habeis' - nome_coluna: 'valor_dh' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'emendas.documentos_habeis' - nome_coluna: 'valor_rateio_dh' - tipo_esperado: 'numeric' - - - name: relatorio_gestao - description: > - Tabela que armazena a situação e o parecer final do Relatório de Gestão - vinculado ao Plano de Ação das emendas especiais. - meta: - tags: - - bronze - columns: - - name: id_relatorio_gestao - description: "Identificador Único do Relatorio de Gestão." - - name: situacao_relatorio_gestao - description: "Situação do Relatório de Gestão" - - name: parecer_relatorio_gestao - description: "Parecer do Relatório de Gestão" - - name: id_plano_acao - description: "Identificador Único do Plano de Ação (PA)." - tests: - - verificacao_tipagem: - nome_tabela: 'emendas.relatorio_gestao' - nome_coluna: 'id_relatorio_gestao' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.relatorio_gestao' - nome_coluna: 'id_plano_acao' - tipo_esperado: 'integer' - - - name: relatorio_gestao_novo - description: > - Tabela que armazena os registros do Novo Relatório de Gestão das Emendas Especiais. - Contém o detalhamento da execução financeira por Plano de Ação, incluindo valores - executados, pendentes e o status de tramitação do relatório. - meta: - tags: - - bronze - columns: - - name: id_relatorio_gestao_novo - description: "Identificador único do registro do novo relatório de gestão." - - name: data_e_hora_relatorio_gestao_novo - description: "Timestamp do momento do registro ou última atualização do relatório." - - name: tipo_relatorio_gestao_novo - description: "Classificação do tipo de relatório enviado pelo executor." - - name: valor_executado_relatorio_gestao_novo - description: "Montante financeiro total que já foi executado e declarado." - - name: valor_pendente_relatorio_gestao_novo - description: "Montante financeiro que ainda aguarda execução ou comprovação." - - name: situacao_relatorio_gestao_novo - description: "Status atual do relatório (ex: Em preenchimento, Enviado, Homologado)." - - name: id_plano_acao - description: "Chave estrangeira que vincula o relatório ao Plano de Ação correspondente." - - name: dt_ingest - description: "Data e hora da ingestão dos dados na camada bronze (UTC-3)." - tests: - - verificacao_tipagem: - nome_tabela: 'emendas.relatorio_gestao_novo' - nome_coluna: 'id_relatorio_gestao_novo' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.relatorio_gestao_novo' - nome_coluna: 'data_e_hora_relatorio_gestao_novo' - tipo_esperado: 'timestamp without time zone' - - verificacao_tipagem: - nome_tabela: 'emendas.relatorio_gestao_novo' - nome_coluna: 'valor_executado_relatorio_gestao_novo' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'emendas.relatorio_gestao_novo' - nome_coluna: 'valor_pendente_relatorio_gestao_novo' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'emendas.relatorio_gestao_novo' - nome_coluna: 'id_plano_acao' - tipo_esperado: 'integer' - - - name: executor - description: > - Tabela com informações detalhadas sobre os executores dos planos de ação das emendas. - Contém dados cadastrais do executor, detalhes do objeto da execução, valores financeiros de custeio - e investimento, além de informações bancárias para a gestão dos recursos. - Os dados são oriundos da API 'executor_especial' do Transferegov. - meta: - tags: - - bronze - columns: - - name: id_plano_acao - description: "Identificador único do Plano de Ação da Proposta." - - name: id_executor - description: "Identificador Único do Executor do Planejamento." - - name: cnpj_executor - description: "CNPJ do ente ou entidade executora." - - name: nome_executor - description: "Nome do Executor." - - name: objeto_executor - description: "Texto detalhado informando o Objeto da Execução." - - name: valor_custeio_executor - description: "Valor de Custeio do objeto a ser atendido pelo executor." - - name: valor_investimento_executor - description: "Valor de Investimento do objeto a ser atendido pelo executor." - - name: ind_recursos_gerenciados_conta_especifica_executor - description: "Indica se os recursos serão gerenciados por conta específica do executor." - - name: codigo_banco_executor - description: "Código da instituição bancária do Executor." - - name: nome_banco_executor - description: "Nome do Banco do Executor." - - name: numero_agencia_executor - description: "Número da Agência Bancária do Executor." - - name: dv_agencia_executor - description: "Dígito Verificador da Agência Bancária." - - name: nome_agencia_executor - description: "Nome da Agência Bancária do Executor." - - name: numero_conta_executor - description: "Número da Conta Bancária do Executor." - - name: dv_conta_executor - description: "Dígito Verificador da Conta Bancária." - - name: codigo_situacao_dado_bancario_executor - description: "Código da Situação da Conta Bancária" - - name: descricao_situacao_dado_bancario_executor - description: "Descrição textual da situação da conta bancária." - - name: dt_ingest - description: "Data e hora (UTC-3 Brasília) da ingestão dos dados para a camada bronze." - - tests: - - verificacao_tipagem: - nome_tabela: 'emendas.executor_especial' - nome_coluna: 'id_plano_acao' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.executor_especial' - nome_coluna: 'id_executor' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.executor_especial' - nome_coluna: 'valor_custeio_executor' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'emendas.executor_especial' - nome_coluna: 'valor_investimento_executor' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'emendas.executor_especial' - nome_coluna: 'numero_agencia_executor' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.executor_especial' - nome_coluna: 'numero_conta_executor' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.executor_especial' - nome_coluna: 'codigo_situacao_dado_bancario_executor' - tipo_esperado: 'integer' - - - name: metas - description: > - Tabela que detalha as metas físicas e financeiras estabelecidas por cada executor. - Contém o planejamento de execução, discriminando valores de emendas, recursos próprios, - rendimentos e doações, além da quantidade física e o tempo estimado (meses) para a meta. - meta: - tags: - - bronze - columns: - - name: id_executor - description: "Identificador Único do Executor do Planejamento." - - name: id_meta - description: "Identificação Única da Meta do Executor." - - name: sequencial_meta - description: "Sequencial numérico usado para ordenação das metas." - - name: nome_meta - description: "Nome ou título resumido da meta." - - name: desc_meta - description: "Descrição detalhada do que será realizado na meta." - - name: un_medida_meta - description: "Unidade de medida da meta." - - name: qt_uniade_meta - description: "Valor de custeio de Emenda Especial." - - name: valor_custeio_emenda_especial_meta - description: "Valor de Investimento de Emenda Especial." - - name: valor_investimento_emenda_especial_meta - description: "Valor de Custeio de Recursos Proprios." - - name: valor_custeio_recursos_proprios_meta - description: "Valor de Investimento de Recursos Proprios." - - name: valor_investimento_recursos_proprios_meta - description: "Valor de investimento aportado como recursos próprios." - - name: valor_custeio_rendimento_meta - description: "Valor de Custeio de Rendimentos." - - name: valor_investimento_rendimento_meta - description: "Valor de investimento originado de rendimentos." - - name: valor_custeio_doacao_meta - description: "Valor de custeio proveniente de doações." - - name: valor_investimento_doacao_meta - description: "Valor de investimento proveniente de doações." - - name: qt_meses_meta - description: "Quantidade de meses prevista para a execução da meta." - - name: dt_ingest - description: "Data e hora (UTC-3 Brasília) da ingestão dos dados para a camada bronze." - - tests: - - verificacao_tipagem: - nome_tabela: 'emendas.meta_especial' - nome_coluna: 'id_executor' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.meta_especial' - nome_coluna: 'id_meta' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.meta_especial' - nome_coluna: 'qt_uniade_meta' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'emendas.meta_especial' - nome_coluna: 'valor_custeio_emenda_especial_meta' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'emendas.meta_especial' - nome_coluna: 'valor_investimento_emenda_especial_meta' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'emendas.meta_especial' - nome_coluna: 'valor_custeio_recursos_proprios_meta' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'emendas.meta_especial' - nome_coluna: 'valor_investimento_recursos_proprios_meta' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'emendas.meta_especial' - nome_coluna: 'qt_meses_meta' - tipo_esperado: 'integer' - - - name: finalidades - description: > - Tabela que detalha as finalidades das emendas especiais, vinculando cada executor às áreas - de políticas públicas beneficiadas. Permite identificar em quais setores (Saúde, Educação, etc.) - o recurso está sendo aplicado conforme a classificação do Transferegov. - meta: - tags: - - bronze - columns: - - name: id_executor - description: "Identificador Único do Executor do Planejamento (Chave de ligação com a tabela de executores)." - - name: cd_area_politica_publica_tipo_pt - description: "Código numérico que identifica o tipo da área de política pública." - - name: area_politica_publica_tipo_pt - description: "Nome descritivo do tipo da área de política pública." - - name: cd_area_politica_publica_pt - description: "Código da área específica de política pública (subdivisão do tipo)." - - name: area_politica_publica_pt - description: "Nome descritivo da área específica de política pública." - - name: dt_ingest - description: "Data e hora (UTC-3 Brasília) da ingestão dos dados para a camada bronze." - - tests: - - verificacao_tipagem: - nome_tabela: 'emendas.finalidade_especial' - nome_coluna: 'id_executor' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.finalidade_especial' - nome_coluna: 'cd_area_politica_publica_tipo_pt' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.finalidade_especial' - nome_coluna: 'cd_area_politica_publica_pt' - tipo_esperado: 'integer' - - - name: tg_emendas - description: > - Tabela com informações de execução orçamentária do SIAFI para empenhos do Tesouro - vinculados a emendas parlamentares. Reúne classificações orçamentárias, autor da emenda, - localização (UF e município) e valores agregados de despesas empenhadas, liquidadas e pagas. - Os dados são extraídos da tabela empenhos_tesouro_emendas_parlamentares do SIAFI, com - padronização de datas e valores monetários. - meta: - tags: - - bronze - columns: - - name: emissao_mes - description: "Mês/ano de emissão da nota de empenho (primeiro dia do mês)." - - name: emissao_dia - description: "Data de emissão da nota de empenho." - - name: programa_governo - description: "Código do programa de governo no orçamento." - - name: programa_governo_descricao - description: "Descrição do programa de governo." - - name: acao_governo - description: "Código da ação de governo associada à emenda." - - name: acao_governo_descricao - description: "Descrição da ação de governo associada à emenda." - - name: autor_emendas_orcamento - description: "Identificador do autor da emenda no orçamento." - - name: autor_emendas_orcamento_descricao - description: "Descrição completa do autor da emenda no orçamento, incluindo indicação da emenda." - - name: autor_emendas_orcamento_nome - description: "Nome do autor da emenda em formato Title Case, extraído do texto completo antes da barra." - - name: uf_pt - description: "UF de aplicação da programação orçamentária (PT)." - - name: uf_pt_descricao - description: "Descrição da UF da programação orçamentária." - - name: municipio_pt - description: "Município de aplicação da programação orçamentária." - - name: ne_ccor - description: "Código da NE/CCOR no SIAFI." - - name: ne_num_processo - description: "Número do processo administrativo associado à NE." - - name: ne_info_complementar - description: "Informações complementares cadastradas na NE." - - name: ne_ccor_descricao - description: "Descrição textual da NE/CCOR." - - name: doc_observacao - description: "Observações adicionais registradas no documento SIAFI." - - name: grupo_despesa - description: "Código do grupo de despesa orçamentária." - - name: grupo_despesa_descricao - description: "Descrição do grupo de despesa orçamentária." - - name: natureza_despesa - description: "Código da natureza de despesa." - - name: natureza_despesa_descricao - description: "Descrição da natureza de despesa." - - name: modalidade_aplicacao - description: "Código da modalidade de aplicação." - - name: modalidade_aplicacao_descricao - description: "Descrição da modalidade de aplicação." - - name: ne_ccor_favorecido - description: "Identificador do favorecido na NE/CCOR." - - name: ne_ccor_favorecido_descricao - description: "Nome/descrição do favorecido na NE/CCOR." - - name: ne_ccor_ano_emissao - description: "Ano de emissão da NE/CCOR." - - name: ptres - description: "PTRES associado à despesa da emenda." - - name: item_informacao - description: "Código do item de informação orçamentária." - - name: item_informacao_descricao - description: "Descrição do item de informação orçamentária." - - name: despesas_empenhadas - description: "Valor total das despesas empenhadas para a combinação de classificações." - - name: despesas_liquidadas - description: "Valor total das despesas liquidadas para a combinação de classificações." - - name: despesas_pagas - description: "Valor total das despesas pagas para a combinação de classificações." - - name: dt_ingest - description: "Data e hora (UTC-3 Brasília) da ingestão dos dados para a camada bronze." - - tests: - - verificacao_tipagem: - nome_tabela: 'emendas.tg_emendas' - nome_coluna: 'emissao_mes' - tipo_esperado: 'date' - - verificacao_tipagem: - nome_tabela: 'emendas.tg_emendas' - nome_coluna: 'emissao_dia' - tipo_esperado: 'date' - - verificacao_tipagem: - nome_tabela: 'emendas.tg_emendas' - nome_coluna: 'programa_governo' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.tg_emendas' - nome_coluna: 'grupo_despesa' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.tg_emendas' - nome_coluna: 'modalidade_aplicacao' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.tg_emendas' - nome_coluna: 'ne_ccor_ano_emissao' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.tg_emendas' - nome_coluna: 'ptres' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.tg_emendas' - nome_coluna: 'despesas_empenhadas' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'emendas.tg_emendas' - nome_coluna: 'despesas_liquidadas' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'emendas.tg_emendas' - nome_coluna: 'despesas_pagas' - tipo_esperado: 'numeric' diff --git a/dbt/mir/models/emendas_dbt/bronze/tg_emendas.sql b/dbt/mir/models/emendas_dbt/bronze/tg_emendas.sql deleted file mode 100644 index e13e8f4d..00000000 --- a/dbt/mir/models/emendas_dbt/bronze/tg_emendas.sql +++ /dev/null @@ -1,53 +0,0 @@ -{{ config(materialized="table") }} - -with - tg_emendas_raw as ( - select - {{ target.schema }}.parse_date(emissao_mes) as emissao_mes, - to_date(emissao_dia, 'DD/MM/YYYY') as emissao_dia, - programa_governo::integer as programa_governo, - programa_governo_descricao::text as programa_governo_descricao, - acao_governo::text as acao_governo, - acao_governo_descricao::text as acao_governo_descricao, - autor_emendas_orcamento::text as autor_emendas_orcamento, - autor_emendas_orcamento_descricao::text as autor_emendas_orcamento_descricao, - initcap( - trim( - regexp_replace( - split_part(autor_emendas_orcamento_descricao, '/', 1), - '\s+', - ' ', - 'g' - ) - ) - ) as autor_emendas_orcamento_nome, - uf_pt::text as uf_pt, - uf_pt_descricao::text as uf_pt_descricao, - municipio_pt::text as municipio_pt, - ne_ccor::text as ne_ccor, - ne_num_processo::text as ne_num_processo, - ne_info_complementar::text as ne_info_complementar, - ne_ccor_descricao::text as ne_ccor_descricao, - doc_observacao::text as doc_observacao, - grupo_despesa::integer as grupo_despesa, - grupo_despesa_descricao::text as grupo_despesa_descricao, - natureza_despesa::text as natureza_despesa, - natureza_despesa_descricao::text as natureza_despesa_descricao, - modalidade_aplicacao::integer as modalidade_aplicacao, - modalidade_aplicacao_descricao::text as modalidade_aplicacao_descricao, - ne_ccor_favorecido::text as ne_ccor_favorecido, - ne_ccor_favorecido_descricao::text as ne_ccor_favorecido_descricao, - ne_ccor_ano_emissao::integer as ne_ccor_ano_emissao, - ptres::integer as ptres, - item_informacao::text as item_informacao, - item_informacao_descricao::text as item_informacao_descricao, - {{ parse_financial_value("despesas_empenhadas") }} as despesas_empenhadas, - {{ parse_financial_value("despesas_liquidadas") }} as despesas_liquidadas, - {{ parse_financial_value("despesas_pagas") }} as despesas_pagas, - (dt_ingest || '-03:00')::timestamptz as dt_ingest - from {{ source("siafi", "empenhos_tesouro_emendas_parlamentares") }} - ) - -select * -from tg_emendas_raw - diff --git a/dbt/mir/models/emendas_dbt/silver/planos_partidos.sql b/dbt/mir/models/emendas_dbt/silver/planos_partidos.sql deleted file mode 100644 index c08d2580..00000000 --- a/dbt/mir/models/emendas_dbt/silver/planos_partidos.sql +++ /dev/null @@ -1,96 +0,0 @@ -{{ config(materialized='table') }} - -WITH bronze_planos_acoes AS ( - SELECT * FROM {{ ref('planos_acoes') }} -), - -bronze_deputados AS ( - SELECT * FROM {{ ref('deputados') }} -), - -bronze_senadores AS ( - SELECT * FROM {{ ref('senadores') }} -), - -parlamentares_unificados AS ( - SELECT - id AS id_parlamentar, - TRIM(UPPER(nome)) AS chave_join_nome, - nome AS nome_parlamentar, - 'Deputado' AS cargo_parlamentar, - siglapartido AS sigla_partido, - siglauf AS uf_parlamentar, - urlfoto AS url_foto, - email - FROM bronze_deputados - - UNION ALL - - SELECT - id AS id_parlamentar, - TRIM(UPPER(nome_parlamentar)) AS chave_join_nome, - nome_parlamentar AS nome_parlamentar, - 'Senador' AS cargo_parlamentar, - sigla_partido AS sigla_partido, - uf AS uf_parlamentar, - url_foto AS url_foto, - email - FROM bronze_senadores -), - -planos_acoes_tratado AS ( - SELECT - *, - TRIM(UPPER(nome_parlamentar_emenda_plano_acao)) AS chave_join_nome - FROM bronze_planos_acoes -), - -final AS ( - SELECT - -- Todas as features de Planos de Ação - pa.id_plano_acao, - pa.codigo_plano_acao, - pa.ano_plano_acao, - pa.modalidade_plano_acao, - pa.situacao_plano_acao, - pa.cnpj_beneficiario_plano_acao, - pa.nome_beneficiario_plano_acao, - pa.uf_beneficiario_plano_acao, - pa.codigo_banco_plano_acao, - pa.codigo_situacao_dado_bancario_plano_acao, - pa.nome_banco_plano_acao, - pa.numero_agencia_plano_acao, - pa.dv_agencia_plano_acao, - pa.numero_conta_plano_acao, - pa.dv_conta_plano_acao, - pa.nome_parlamentar_emenda_plano_acao, - pa.ano_emenda_parlamentar_plano_acao, - pa.codigo_parlamentar_emenda_plano_acao, - pa.sequencial_emenda_parlamentar_plano_acao, - pa.numero_emenda_parlamentar_plano_acao, - pa.codigo_emenda_parlamentar_formatado_plano_acao, - pa.codigo_descricao_areas_politicas_publicas_plano_acao, - pa.descricao_programacao_orcamentaria_plano_acao, - pa.motivo_impedimento_plano_acao, - pa.valor_custeio_plano_acao, - pa.valor_investimento_plano_acao, - pa.id_programa, - - -- Features unificadas dos Parlamentares - parl.id_parlamentar, - parl.cargo_parlamentar, - parl.nome_parlamentar, - parl.sigla_partido, - parl.uf_parlamentar, - parl.url_foto, - parl.email, - - -- Data de ingestão (mantendo a da tabela fato) - pa.dt_ingest - - FROM planos_acoes_tratado pa - LEFT JOIN parlamentares_unificados parl - ON pa.chave_join_nome = parl.chave_join_nome -) - -SELECT * FROM final \ No newline at end of file diff --git a/dbt/mir/models/emendas_dbt/silver/schema.yml b/dbt/mir/models/emendas_dbt/silver/schema.yml deleted file mode 100644 index 4500ba9f..00000000 --- a/dbt/mir/models/emendas_dbt/silver/schema.yml +++ /dev/null @@ -1,168 +0,0 @@ -version: 2 - -models: - - - name: planos_partidos - description: > - Tabela silver que integra as informações dos planos de ação especiais relacionados a emendas - parlamentares do TransfereGov com metadados de parlamentares (deputados e senadores). - A partir da tabela bronze planos_acoes e das bases de deputados e senadores, enriquece cada - plano de ação com dados de identificação do parlamentar, partido, UF, foto e e-mail. - meta: - tags: - - silver - columns: - # Colunas de planos de ação (herdadas da camada bronze) - - name: id_plano_acao - description: > - Identificador único do Plano de Ação (PA). - - name: codigo_plano_acao - description: > - Código do Programa concatenado com o ID do Plano de Ação. - - name: ano_plano_acao - description: > - Ano de criação do Plano de Ação. - - name: modalidade_plano_acao - description: > - Modalidade de Transferência do Plano de Ação. - - name: situacao_plano_acao - description: > - Situação do Plano de Ação. - - name: cnpj_beneficiario_plano_acao - description: > - CNPJ – Cadastro Nacional de Pessoa Jurídica do Beneficiário do Plano de Ação. - - name: nome_beneficiario_plano_acao - description: > - Nome do Beneficiário do Plano de Ação. - - name: uf_beneficiario_plano_acao - description: > - Sigla da Unidade de Federação do beneficiário. - - name: codigo_banco_plano_acao - description: > - Código do Banco do Plano de Ação. - - name: codigo_situacao_dado_bancario_plano_acao - description: > - Código da Situação da Conta Corrente do Plano de Ação. - - name: nome_banco_plano_acao - description: > - Nome do Banco do Plano de Ação. - - name: numero_agencia_plano_acao - description: > - Número da Agência Bancária da Conta Corrente do Plano de Ação. - - name: dv_agencia_plano_acao - description: > - Dígito Verificador da Agência Bancária da Conta Corrente do Plano de Ação. - - name: numero_conta_plano_acao - description: > - Número da Conta Corrente do Plano de Ação. - - name: dv_conta_plano_acao - description: > - Dígito Verificador da Conta Corrente do Plano de Ação. - - name: nome_parlamentar_emenda_plano_acao - description: > - Nome do Parlamentar Autor da Emenda vinculado ao Plano de Ação. - - name: ano_emenda_parlamentar_plano_acao - description: > - Ano da Emenda Parlamentar associada ao Plano de Ação. - - name: codigo_parlamentar_emenda_plano_acao - description: > - Código do Parlamentar Autor da Emenda. - - name: sequencial_emenda_parlamentar_plano_acao - description: > - Sequencial da Emenda por Parlamentar no Ano. - - name: numero_emenda_parlamentar_plano_acao - description: > - Concatenação do Ano, Código e Sequencial do Parlamentar, formando o identificador da emenda. - - name: codigo_emenda_parlamentar_formatado_plano_acao - description: > - Código formatado da Emenda Parlamentar associada ao Plano de Ação. - - name: codigo_descricao_areas_politicas_publicas_plano_acao - description: > - Concatenação dos códigos e descrições dos tipos das áreas de políticas públicas - com os códigos e descrições das áreas das políticas públicas. - - name: descricao_programacao_orcamentaria_plano_acao - description: > - Concatenação das programações orçamentárias constantes da Lei Orçamentária do ente - beneficiado na qual o recurso será apropriado. - - name: motivo_impedimento_plano_acao - description: > - Motivo do impedimento do Plano de Ação, quando existente. - - name: valor_custeio_plano_acao - description: > - Valor consolidado de custeio das emendas parlamentares do Plano de Ação. - - name: valor_investimento_plano_acao - description: > - Valor consolidado de investimento das emendas parlamentares do Plano de Ação. - - name: id_programa - description: > - Identificador único do Programa associado ao Plano de Ação. - # Colunas de metadados dos parlamentares - - name: id_parlamentar - description: > - Identificador único do parlamentar na base unificada de deputados e senadores. - - name: cargo_parlamentar - description: > - Cargo do parlamentar responsável pela emenda (por exemplo, Deputado ou Senador). - - name: nome_parlamentar - description: > - Nome do parlamentar conforme registrado na base de origem (Câmara dos Deputados ou Senado Federal). - - name: sigla_partido - description: > - Sigla do partido ao qual o parlamentar está filiado. - - name: uf_parlamentar - description: > - Sigla da Unidade Federativa (UF) que o parlamentar representa. - - name: url_foto - description: > - URL da foto oficial do parlamentar na base de origem. - - name: email - description: > - Endereço de e-mail institucional do parlamentar. - - name: dt_ingest - description: > - Data e hora (UTC-3 Brasília) mais recente de ingestão dos dados das tabelas fonte utilizadas neste modelo. - tests: - - verificacao_tipagem: - nome_tabela: 'emendas.planos_partidos' - nome_coluna: 'id_plano_acao' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.planos_partidos' - nome_coluna: 'ano_plano_acao' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.planos_partidos' - nome_coluna: 'codigo_situacao_dado_bancario_plano_acao' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.planos_partidos' - nome_coluna: 'numero_agencia_plano_acao' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.planos_partidos' - nome_coluna: 'numero_conta_plano_acao' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.planos_partidos' - nome_coluna: 'sequencial_emenda_parlamentar_plano_acao' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.planos_partidos' - nome_coluna: 'valor_custeio_plano_acao' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'emendas.planos_partidos' - nome_coluna: 'valor_investimento_plano_acao' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'emendas.planos_partidos' - nome_coluna: 'id_programa' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.planos_partidos' - nome_coluna: 'id_parlamentar' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'emendas.planos_partidos' - nome_coluna: 'dt_ingest' - tipo_esperado: 'timestamp with time zone' \ No newline at end of file diff --git a/dbt/mir/models/empenhos_ted_dbt/bronze/empenhos_tesouro_ted.sql b/dbt/mir/models/empenhos_ted_dbt/bronze/empenhos_tesouro_ted.sql deleted file mode 100644 index 72a6916f..00000000 --- a/dbt/mir/models/empenhos_ted_dbt/bronze/empenhos_tesouro_ted.sql +++ /dev/null @@ -1,37 +0,0 @@ -{{ config(materialized="table") }} - - -with - empenhos_teds_raw as ( - select - programa_governo::text as programa_governo, - programa_governo_descricao::text as programa_governo_descricao, - acao_governo::text as acao_governo, - acao_governo_descricao::text as acao_governo_descricao, - emissao_mes::text as emissao_mes, - emissao_dia::text as emissao_dia, - ne_ccor::text as ne_ccor, - regexp_replace(ne_num_processo, '[./-]', '', 'g') as ne_num_processo, - ne_info_complementar::text as ne_info_complementar, - ne_ccor_descricao::text as ne_ccor_descricao, - doc_observacao::text as doc_observacao, - natureza_despesa::text as natureza_despesa, - natureza_despesa_descricao::text as natureza_despesa_descricao, - upper(ne_ccor_favorecido::text) as ne_ccor_favorecido, - ne_ccor_favorecido_descricao::text as ne_ccor_favorecido_descricao, - ne_ccor_ano_emissao::integer as ne_ccor_ano_emissao, - ptres::text as ptres, - fonte_recursos_detalhada::text as fonte_recursos_detalhada, - fonte_recursos_detalhada_descricao::text as fonte_recursos_detalhada_descricao, - {{ parse_financial_value("despesas_empenhadas") }} as despesas_empenhadas, - {{ parse_financial_value("despesas_liquidadas") }} as despesas_liquidadas, - {{ parse_financial_value("despesas_pagas") }} as despesas_pagas, - {{ parse_financial_value("restos_a_pagar_inscritos") }} as restos_a_pagar_inscritos, - {{ parse_financial_value("restos_a_pagar_pagos") }} as restos_a_pagar_pagos, - (dt_ingest || '-03:00')::timestamptz as dt_ingest - from {{ source("siafi", "empenhos_tesouro_parlamentares") }} - where ne_ccor_ano_emissao ~ '^[0-9]{4}$' - ) - -select * -from empenhos_teds_raw \ No newline at end of file diff --git a/dbt/mir/models/empenhos_ted_dbt/bronze/schema.yaml b/dbt/mir/models/empenhos_ted_dbt/bronze/schema.yaml deleted file mode 100644 index ca6fa6a5..00000000 --- a/dbt/mir/models/empenhos_ted_dbt/bronze/schema.yaml +++ /dev/null @@ -1,102 +0,0 @@ -version: 2 - -models: - - name: empenhos_tesouro_ted - description: > - Tabela da camada bronze contendo informações detalhadas sobre os empenhos do Tesouro Gerencial - vinculados a emendas parlamentares e TEDs. - A tabela realiza a limpeza do número do processo, padronização de nomes de favorecidos - e conversão de valores financeiros de string para numeric(15,2) via macro. - meta: - tags: - - bronze - columns: - - name: programa_governo - description: > - Código identificador do programa de governo associado ao empenho. - - name: programa_governo_descricao - description: > - Descrição textual do programa de governo. - - name: acao_governo - description: > - Código da ação orçamentária (Ação de Governo). - - name: acao_governo_descricao - description: > - Descrição da ação orçamentária. - - name: emissao_mes - description: > - Mês de emissão da nota de empenho. - - name: emissao_dia - description: > - Dia específico da emissão da nota de empenho. - - name: ne_ccor - description: > - Número completo da nota de empenho (Chave natural principal). - - name: ne_num_processo - description: > - Número do processo administrativo, limpo de caracteres especiais (pontos, barras, hifens) via regex. - - name: ne_info_complementar - description: > - Informações adicionais registradas na nota de empenho. - - name: ne_ccor_descricao - description: > - Descrição detalhada do item ou serviço empenhado. - - name: doc_observacao - description: > - Observações registradas no documento fiscal ou contábil. - - name: natureza_despesa - description: > - Código da natureza da despesa (ex: 339030). - - name: natureza_despesa_descricao - description: > - Descrição da categoria da natureza de despesa. - - name: ne_ccor_favorecido - description: > - CNPJ ou CPF do favorecido do empenho, convertido para caixa alta. - - name: ne_ccor_favorecido_descricao - description: > - Nome ou Razão Social do favorecido. - - name: ne_ccor_ano_emissao - description: > - Ano de emissão do empenho (YYYY), validado via regex para garantir 4 dígitos numéricos. - - name: ptres - description: > - Programa de Trabalho Resumido (PTRES). - - name: fonte_recursos_detalhada - description: > - Código detalhado da fonte de financiamento. - - name: fonte_recursos_detalhada_descricao - description: > - Descrição da fonte de recursos. - - name: despesas_empenhadas - description: > - Valor total das despesas empenhadas, convertido para numeric(15,2). - - name: despesas_liquidadas - description: > - Valor das despesas que já passaram pela liquidação, convertido para numeric(15,2). - - name: despesas_pagas - description: > - Valor efetivamente pago ao favorecido, convertido para numeric(15,2). - - name: restos_a_pagar_inscritos - description: > - Valor inscrito em Restos a Pagar (RP), convertido para numeric(15,2). - - name: restos_a_pagar_pagos - description: > - Valor de Restos a Pagar que já foram quitados, convertido para numeric(15,2). - - name: dt_ingest - description: > - Timestamp da ingestão dos dados na camada raw, ajustado para o fuso horário de Brasília (UTC-3). - - tests: - - verificacao_tipagem: - nome_tabela: 'mir.empenhos_tesouro_parlamentares' - nome_coluna: 'ne_ccor_ano_emissao' - tipo_esperado: 'integer' - - verificacao_tipagem: - nome_tabela: 'mir.empenhos_tesouro_parlamentares' - nome_coluna: 'despesas_empenhadas' - tipo_esperado: 'numeric' - - verificacao_tipagem: - nome_tabela: 'mir.empenhos_tesouro_parlamentares' - nome_coluna: 'restos_a_pagar_inscritos' - tipo_esperado: 'numeric' \ No newline at end of file diff --git a/dbt/mir/models/metadata/models_metadata.sql b/dbt/mir/models/metadata/models_metadata.sql deleted file mode 100644 index f1981994..00000000 --- a/dbt/mir/models/metadata/models_metadata.sql +++ /dev/null @@ -1,67 +0,0 @@ -{{ - config( - materialized='incremental', - unique_key=['schema_name', 'table_name'], - on_schema_change='sync_all_columns' - ) -}} - -{# - Tabela de Metadados dos Modelos dbt - =================================== - - Esta tabela armazena metadados de todos os modelos executados no dbt. - - Campos principais: - - schema_name: Schema do modelo - - table_name: Nome da tabela/modelo - - dt_transform: Data da última transformação (quando o modelo foi executado) - - run_id: ID único da execução do dbt - - A tabela é atualizada de forma incremental, mantendo apenas o registro - mais recente para cada combinação de schema + table_name. -#} - -WITH dbt_models AS ( - {# - Usando a função graph do dbt para iterar sobre todos os modelos do projeto. - Isso garante que capturamos metadados de todos os modelos definidos. - #} - {% set models_data = [] %} - - {% for node in graph.nodes.values() %} - {% if node.resource_type == 'model' %} - {% do models_data.append({ - 'schema_name': node.schema, - 'table_name': node.name, - 'database_name': node.database, - 'materialization': node.config.materialized, - 'description': node.description | default('') | replace("'", "''") - }) %} - {% endif %} - {% endfor %} - - {% for model in models_data %} - SELECT - '{{ model.schema_name }}' AS schema_name, - '{{ model.table_name }}' AS table_name, - '{{ model.database_name }}' AS database_name, - '{{ model.materialization }}' AS materialization, - '{{ model.description[:500] }}' AS description, - ('{{ run_started_at }}'::TIMESTAMP AT TIME ZONE 'UTC' AT TIME ZONE 'America/Sao_Paulo') AS dt_transform, - '{{ invocation_id }}' AS run_id - {% if not loop.last %} - UNION ALL - {% endif %} - {% endfor %} -) - -SELECT - schema_name, - table_name, - database_name, - materialization, - description, - dt_transform, - run_id -FROM dbt_models diff --git a/dbt/mir/models/metadata/schema.yml b/dbt/mir/models/metadata/schema.yml deleted file mode 100644 index e4fce0ab..00000000 --- a/dbt/mir/models/metadata/schema.yml +++ /dev/null @@ -1,46 +0,0 @@ -# yaml-language-server: $schema=https://raw.githubusercontent.com/dbt-labs/dbt-jsonschema/main/schemas/latest/dbt_yml_files-latest.json - -version: 2 - -models: - - name: models_metadata - description: > - Tabela central de metadados que armazena informações sobre todos os modelos dbt executados. - Cada linha representa um modelo único, identificado pela combinação de schema e table_name. - A tabela é atualizada de forma incremental, mantendo histórico das execuções. - meta: - tags: - - metadata - - governance - columns: - - name: schema_name - description: Nome do schema onde o modelo está localizado. - tests: - - not_null - - - name: table_name - description: Nome da tabela/modelo. - tests: - - not_null - - - name: database_name - description: Nome do banco de dados onde o modelo está materializado. - - - name: materialization - description: Tipo de materialização do modelo (table, view, incremental, etc). - - - name: description - description: Descrição do modelo extraída do schema.yml. - - - name: dt_transform - description: > - Data e hora em que o modelo foi transformado/executado pela última vez. - Corresponde ao momento em que a execução do dbt foi iniciada (run_started_at). - Timezone: America/Sao_Paulo (UTC-3). - tests: - - not_null - - - name: run_id - description: > - Identificador único da execução do dbt (invocation_id). - Permite rastrear qual execução gerou a transformação. diff --git a/dbt/mir/models/sources.yml b/dbt/mir/models/sources.yml deleted file mode 100644 index 611e3c56..00000000 --- a/dbt/mir/models/sources.yml +++ /dev/null @@ -1,34 +0,0 @@ -version: 2 - -sources: - - name: transferegov_emendas - schema: transferegov_emendas - tables: - - name: programas_especiais - - name: planos_acao_especiais - - name: empenhos_especiais - - name: ordens_bancarias_especiais - - name: historico_pagamentos_especiais - - name: plano_trabalho_especial - - name: documentos_habeis_especiais - - name: relatorio_gestao_especial - - name: relatorios_gestao_novo_especial - - name: executor_especial - - name: metas_especiais - - name: finalidades_especiais - - - name: camara_deputados - schema: camara_deputados - tables: - - name: deputados - - - name: senado_federal - schema: senado_federal - tables: - - name: senadores - - - name: siafi - schema: siafi - tables: - - name: empenhos_tesouro_parlamentares - - name: empenhos_tesouro_emendas_parlamentares \ No newline at end of file diff --git a/dbt/mir/profiles.yml b/dbt/mir/profiles.yml deleted file mode 100755 index c5ef73cc..00000000 --- a/dbt/mir/profiles.yml +++ /dev/null @@ -1,11 +0,0 @@ -mir: - target: prod - outputs: - prod: - type: postgres - host: "{{ env_var('DB_DW_HOST_MIR', 'postgres') }}" - user: "{{ env_var('DB_DW_USER_MIR', 'postgres_dw') }}" - password: "{{ env_var('DB_DW_PASSWORD_MIR', 'postgres_dw') }}" - port: "{{ env_var('DB_DW_PORT_MIR', '5432') | int }}" - dbname: "{{ env_var('DB_DW_DBNAME_MIR', 'data_warehouse') }}" - schema: "{{ env_var('DB_DW_SCHEMA_MIR', 'mir') }}" \ No newline at end of file diff --git a/dbt/mir/seeds/partidos_logo.csv b/dbt/mir/seeds/partidos_logo.csv deleted file mode 100644 index 2dfcb601..00000000 --- a/dbt/mir/seeds/partidos_logo.csv +++ /dev/null @@ -1,29 +0,0 @@ -sigla,nome,logo_url -AVANTE,Avante,https://upload.wikimedia.org/wikipedia/commons/7/7a/Bandeira-partido-avante.png -CIDADANIA,Cidadania,https://upload.wikimedia.org/wikipedia/commons/d/d7/Logo_do_Cidadania_23.png -DC,Democracia Cristã,https://upload.wikimedia.org/wikipedia/commons/c/cd/Bandeira-democracia-crist%C3%A3.png -MDB,Movimento Democrático Brasileiro,https://upload.wikimedia.org/wikipedia/commons/a/a8/Movimento_Democr%C3%A1tico_Brasileiro_%282017%29.png -MISSÃO,Missão,https://upload.wikimedia.org/wikipedia/commons/6/6e/Partido_Miss%C3%A3o_logo_%28dark%29.svg -NOVO,Partido Novo,https://upload.wikimedia.org/wikipedia/commons/6/64/Partido_Novo_logo_%282020%29.svg -PCdoB,Partido Comunista do Brasil,https://upload.wikimedia.org/wikipedia/commons/e/e5/PCdoB_flag.svg -PCO,Partido da Causa Operária,https://upload.wikimedia.org/wikipedia/commons/4/4a/Bandeira_do_Partido_da_Causa_Oper%C3%A1ria%2C_do_Brasil.png -PDT,Partido Democrático Trabalhista,https://upload.wikimedia.org/wikipedia/commons/5/51/LogoPDT.svg -PL,Partido Liberal,https://upload.wikimedia.org/wikipedia/commons/1/12/Partido_Liberal_%28Brazil%29_logo.svg -PMB,Partido da Mulher Brasileira,https://upload.wikimedia.org/wikipedia/commons/f/f2/Logomarca_do_Partido_da_Mulher_Brasileira_%282008%29.png -PODE,Podemos,https://upload.wikimedia.org/wikipedia/commons/9/99/Logo_Podemos_20.png -PP,Progressistas,https://upload.wikimedia.org/wikipedia/commons/0/0d/Partido_Progressista_%28Brazil%29_logo.svg -PRD,Partido Renovação Democrática,https://upload.wikimedia.org/wikipedia/commons/2/2c/PRD_logo.png -PROS,Partido Republicano da Ordem Social,https://upload.wikimedia.org/wikipedia/commons/8/8a/PROS_logo.png -PRTB,Partido Renovador Trabalhista Brasileiro,https://upload.wikimedia.org/wikipedia/commons/7/76/PRTB-LOGO-04-1024x393.png -PSB,Partido Socialista Brasileiro,https://upload.wikimedia.org/wikipedia/commons/1/19/Partido_Socialista_Brasileiro_logo.png -PSC,Partido Social Cristão,https://upload.wikimedia.org/wikipedia/commons/a/a9/PSC_logo%28cortado%29.png -PSD,Partido Social Democrático,https://upload.wikimedia.org/wikipedia/commons/0/0c/PSD_Brazil_logo.svg -PSDB,Partido da Social Democracia Brasileira,https://upload.wikimedia.org/wikipedia/commons/9/9c/Logomarca_do_Partido_da_Social_Democracia_Brasileira.png -PSOL,Partido Socialismo e Liberdade,https://upload.wikimedia.org/wikipedia/commons/f/f4/Logo_PSOL_roxo.svg -PT,Partido dos Trabalhadores,https://upload.wikimedia.org/wikipedia/commons/b/be/Logo_do_Partido_dos_Trabalhadores.svg -PV,Partido Verde,https://upload.wikimedia.org/wikipedia/commons/4/46/Logomarca_do_Partido_Verde.svg -REDE,Rede Sustentabilidade,https://upload.wikimedia.org/wikipedia/commons/2/2d/Logomarca_da_Rede_Sustentabilidade_(REDE)%2C_do_Brasil.png -REPUBLICANOS,Republicanos,https://upload.wikimedia.org/wikipedia/commons/3/3c/Logomarca_do_Partido_Republicano_Brasileiro_%282005%E2%80%932012%29.png -SOLIDARIEDADE,Solidariedade,https://upload.wikimedia.org/wikipedia/commons/f/fe/Logomarca_do_Partido_Solidariedade.png -UNIÃO,União Brasil,https://upload.wikimedia.org/wikipedia/commons/7/73/Uni%C3%A3o_Brasil_logo.svg -UP,Unidade Popular,https://upload.wikimedia.org/wikipedia/commons/b/bd/UP_Flag2.svg \ No newline at end of file diff --git a/dbt/mir/seeds/partidos_map.csv b/dbt/mir/seeds/partidos_map.csv deleted file mode 100644 index ee1d85fe..00000000 --- a/dbt/mir/seeds/partidos_map.csv +++ /dev/null @@ -1,2 +0,0 @@ -sigla_origem,sigla_canonica -PODEMOS,PODE \ No newline at end of file diff --git a/dbt/mir/seeds/schema.yml b/dbt/mir/seeds/schema.yml deleted file mode 100644 index e5676468..00000000 --- a/dbt/mir/seeds/schema.yml +++ /dev/null @@ -1,14 +0,0 @@ -version: 2 - -seeds: - - name: partidos_logo - config: - column_types: - sigla: text - nome: text - logo_url: text - - name: partidos_map - config: - column_types: - sigla_origem: text - sigla_canonica: text diff --git a/dbt/mir/tests/test_parlamentares_logo_partido.sql b/dbt/mir/tests/test_parlamentares_logo_partido.sql deleted file mode 100644 index bab1d974..00000000 --- a/dbt/mir/tests/test_parlamentares_logo_partido.sql +++ /dev/null @@ -1,19 +0,0 @@ --- Falha (ou gera warning) se existir algum parlamentar com sigla de partido --- que não tenha correspondência no seed partidos_logo. - -{{ config(severity='warn') }} - -with parlamentares as ( - select * from {{ ref('parlamentares') }} -), -partidos_logo as ( - select * from {{ ref('partidos_logo') }} -) - -select distinct - p.sigla_partido -from parlamentares p -left join partidos_logo pl - on upper(trim(p.sigla_partido)) = upper(trim(pl.sigla)) -where p.sigla_partido is not null - and pl.sigla is null diff --git a/infra/airflow/prune_stale_dags.py b/infra/airflow/prune_stale_dags.py new file mode 100644 index 00000000..83444626 --- /dev/null +++ b/infra/airflow/prune_stale_dags.py @@ -0,0 +1,36 @@ +import logging +import os + +from airflow.api.common.delete_dag import delete_dag +from airflow.configuration import conf +from airflow.dag_processing.dagbag import DagBag +from airflow.models.dag import DagModel +from airflow.utils.session import create_session +from sqlalchemy import select + + +logging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s") + + +def main() -> None: + dags_folder = os.environ.get("AIRFLOW__CORE__DAGS_FOLDER") or conf.get("core", "dags_folder") + dagbag = DagBag(dag_folder=dags_folder, include_examples=False) + local_dag_ids = set(dagbag.dags) + + with create_session() as session: + db_dag_ids = set(session.scalars(select(DagModel.dag_id)).all()) + stale_dag_ids = sorted(db_dag_ids - local_dag_ids) + + if not stale_dag_ids: + logging.info("No stale DAGs found in Airflow metadata DB.") + return + + logging.info("Pruning %d stale DAG(s): %s", len(stale_dag_ids), ", ".join(stale_dag_ids)) + + for dag_id in stale_dag_ids: + deleted_count = delete_dag(dag_id=dag_id, session=session) + logging.info("Pruned stale DAG %s (%d record(s) removed).", dag_id, deleted_count) + + +if __name__ == "__main__": + main() diff --git a/infra/airflow/simple_auth_manager_passwords.json b/infra/airflow/simple_auth_manager_passwords.json new file mode 100644 index 00000000..438dc579 --- /dev/null +++ b/infra/airflow/simple_auth_manager_passwords.json @@ -0,0 +1 @@ +{"airflow": "airflow"} diff --git a/infra/docker-compose.yml b/infra/docker-compose.yml index 2336e43f..e0d1cc82 100644 --- a/infra/docker-compose.yml +++ b/infra/docker-compose.yml @@ -7,19 +7,20 @@ x-airflow-common: &airflow-common dockerfile: infra/docker/airflow/Dockerfile target: ${AIRFLOW_BUILD_TARGET:-airflow-dev} args: - AIRFLOW_VERSION: ${AIRFLOW_VERSION:-2.8.1} + AIRFLOW_VERSION: ${AIRFLOW_VERSION:-3.2.2} PYTHON_VERSION: ${PYTHON_VERSION:-3.11} user: "${AIRFLOW_UID:-50000}:0" env_file: - ../.env volumes: - ./airflow/airflow.cfg:/opt/airflow/airflow.cfg + - ./airflow/prune_stale_dags.py:/opt/airflow/prune_stale_dags.py:ro - ../dags:/opt/airflow/dags/ - ../plugins:/opt/airflow/plugins/ - ../helpers:/opt/airflow/helpers/ - ../templates:/opt/airflow/templates/ - ../dbt:/opt/airflow/dbt/ - - ../dbt/ipea/profiles.yml:/opt/airflow/.dbt/profiles.yml + - ../dbt/minc/profiles.yml:/opt/airflow/.dbt/profiles.yml depends_on: &airflow-common-depends-on postgres: condition: service_healthy @@ -27,29 +28,27 @@ x-airflow-common: &airflow-common # Common environment variables for Airflow x-airflow-environment: &airflow-common-env AIRFLOW__CORE__DEFAULT_TIMEZONE: 'America/Sao_Paulo' - AIRFLOW__CORE__ENABLE_XCOM_PICKLING: 'true' AIRFLOW__CORE__EXECUTOR: LocalExecutor AIRFLOW__CORE__FERNET_KEY: ${AIRFLOW__CORE__FERNET_KEY:-} AIRFLOW__CORE__LOAD_EXAMPLES: 'false' AIRFLOW__CORE__TEST_CONNECTION: Enabled AIRFLOW__CORE__MAX_MAP_LENGTH: 15000 - AIRFLOW__API__AUTH_BACKENDS: airflow.api.auth.backend.basic_auth + AIRFLOW__CORE__SIMPLE_AUTH_MANAGER_USERS: airflow:admin + AIRFLOW__CORE__SIMPLE_AUTH_MANAGER_PASSWORDS_FILE: /opt/airflow/simple_auth_manager_passwords.json AIRFLOW__DATABASE__SQL_ALCHEMY_CONN: postgresql+psycopg2://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@postgres/airflow AIRFLOW__EMAIL__DEFAULT_EMAIL_ON_RETRY: 'false' AIRFLOW__EMAIL__DEFAULT_EMAIL_ON_FAILURE: 'false' AIRFLOW__WEBSERVER__DEFAULT_UI_TIMEZONE: 'America/Sao_Paulo' AIRFLOW__WEBSERVER__INSTANCE_NAME: "Ipea - Local Dev!" - AIRFLOW__WEBSERVER__NAVBAR_COLOR: '#98DFFF' + AIRFLOW__WEBSERVER__NAVBAR_COLOR: '#112130' AIRFLOW__WEBSERVER__RELOAD_ON_PLUGIN_CHANGE: 'true' - AIRFLOW__WEBSERVER__SECRET_KEY: '42' + AIRFLOW__API__SECRET_KEY: ${AIRFLOW__API__SECRET_KEY:-local-dev-airflow-secret-key} PYTHONPATH: "/opt/airflow/dags:/opt/airflow/plugins:/opt/airflow/helpers" _AIRFLOW_DB_MIGRATE: 'true' - _AIRFLOW_WWW_USER_CREATE: 'true' - _AIRFLOW_WWW_USER_USERNAME: ${_AIRFLOW_WWW_USER_USERNAME:-airflow} - _AIRFLOW_WWW_USER_PASSWORD: ${_AIRFLOW_WWW_USER_PASSWORD:-airflow} AIRFLOW__CORE__PLUGINS_FOLDER: /opt/airflow/plugins AIRFLOW__CORE__DAGS_FOLDER: /opt/airflow/dags AIRFLOW_REPO_BASE: /opt/airflow + AIRFLOW_PRUNE_STALE_DAGS: ${AIRFLOW_PRUNE_STALE_DAGS:-true} # A ENV AIRFLOW_REPO_BASE É IMPORTANTE PARA SINCRONIZAR COM O SISTEMA DE PASTAS # DO AIRFLOW EM HOMOLOG E PROD, ELES POSSUEM UMA ESTRUTURA DE PASTAS DIFERENTE # USAR ESSA ENV NOS CÓDIGOS PARA NÃO HAVER CONFLITOS @@ -58,14 +57,40 @@ services: # Airflow Services airflow: <<: *airflow-common - # Usamos o comando de standalone aqui para não rodar múltiplos containers - # do airflow localmente e assim melhorar a velocidade inicialização - # doc do standalone: https://airflow.apache.org/docs/apache-airflow/2.8.1/start.html - command: standalone + # Usamos standalone para não rodar múltiplos containers localmente. + # A poda automática remove DAGs órfãs do metadata DB quando arquivos são apagados. + command: + - bash + - -c + - | + set -euo pipefail + + airflow standalone & + airflow_pid=$$! + + trap 'kill -TERM "$$airflow_pid" 2>/dev/null || true; wait "$$airflow_pid" 2>/dev/null || true' TERM INT + + if [[ "${AIRFLOW_PRUNE_STALE_DAGS:-true}" == "true" ]]; then + for _ in {1..60}; do + if ! kill -0 "$$airflow_pid" 2>/dev/null; then + wait "$$airflow_pid" + exit $? + fi + + if curl --fail --silent http://localhost:8080/api/v2/monitor/health >/dev/null; then + python /opt/airflow/prune_stale_dags.py || true + break + fi + + sleep 2 + done + fi + + wait "$$airflow_pid" ports: - "8080:8080" healthcheck: - test: [ "CMD", "curl", "--fail", "http://localhost:8080/health" ] + test: [ "CMD", "curl", "--fail", "http://localhost:8080/api/v2/monitor/health" ] interval: 10s timeout: 60s start_period: 60s @@ -103,8 +128,8 @@ services: - dev environment: AIRFLOW_API_URL: http://airflow:8080 - AIRFLOW_USERNAME: ${_AIRFLOW_WWW_USER_USERNAME:-airflow} - AIRFLOW_PASSWORD: ${_AIRFLOW_WWW_USER_PASSWORD:-airflow} + AIRFLOW_USERNAME: ${AIRFLOW_USERNAME:-airflow} + AIRFLOW_PASSWORD: ${AIRFLOW_PASSWORD:-airflow} AF_READ_ONLY: ${AF_READ_ONLY:-false} MCP_TRANSPORT: http MCP_HOST: 0.0.0.0 diff --git a/infra/docker/airflow/Dockerfile b/infra/docker/airflow/Dockerfile index 259fc88d..614e39bf 100644 --- a/infra/docker/airflow/Dockerfile +++ b/infra/docker/airflow/Dockerfile @@ -1,4 +1,4 @@ -ARG AIRFLOW_VERSION=2.8.1 +ARG AIRFLOW_VERSION=3.2.2 ARG PYTHON_VERSION=3.11 FROM apache/airflow:${AIRFLOW_VERSION}-python${PYTHON_VERSION} AS airflow-base @@ -43,22 +43,30 @@ RUN apt-get update \ USER airflow WORKDIR ${AIRFLOW_HOME} +COPY --chown=airflow:0 infra/airflow/simple_auth_manager_passwords.json ./simple_auth_manager_passwords.json + FROM airflow-base AS airflow-prod +ARG AIRFLOW_VERSION COPY requirements.txt ./requirements.txt -RUN python -m pip install --no-cache-dir -r requirements.txt \ +RUN python -m pip install --no-cache-dir "apache-airflow==${AIRFLOW_VERSION}" -r requirements.txt \ + && python -c "import airflow, sys; expected='${AIRFLOW_VERSION}'; actual=airflow.__version__; print(f'Airflow {actual}'); sys.exit(0 if actual == expected else 1)" \ + && python -m pip check \ && rm -f requirements.txt ENV ENVIRONMENT=prod FROM airflow-base AS airflow-dev +ARG AIRFLOW_VERSION COPY requirements.txt ./requirements.txt -RUN python -m pip install --no-cache-dir -r requirements.txt \ +RUN python -m pip install --no-cache-dir "apache-airflow==${AIRFLOW_VERSION}" -r requirements.txt \ + && python -c "import airflow, sys; expected='${AIRFLOW_VERSION}'; actual=airflow.__version__; print(f'Airflow {actual}'); sys.exit(0 if actual == expected else 1)" \ + && python -m pip check \ && rm -f requirements.txt ENV ENVIRONMENT=dev diff --git a/infra/env/.env.example b/infra/env/.env.example index 433bdbac..ee74cfdc 100644 --- a/infra/env/.env.example +++ b/infra/env/.env.example @@ -1,6 +1,6 @@ AIRFLOW_UID=50000 AIRFLOW_HOME=/opt/airflow -AIRFLOW_VERSION=2.8.1 +AIRFLOW_VERSION=3.2.2 PYTHON_VERSION=3.11 AIRFLOW_BUILD_TARGET=airflow-dev @@ -9,7 +9,8 @@ POSTGRES_USER=postgres POSTGRES_PASSWORD=postgres AIRFLOW__CORE__FERNET_KEY= -_AIRFLOW_WWW_USER_USERNAME=airflow -_AIRFLOW_WWW_USER_PASSWORD=airflow +AIRFLOW_USERNAME=airflow +AIRFLOW_PASSWORD=airflow +AIRFLOW_PRUNE_STALE_DAGS=true AF_READ_ONLY=false diff --git a/local.env b/local.env index d1da9b84..0713ae25 100644 --- a/local.env +++ b/local.env @@ -3,8 +3,8 @@ AIRFLOW_IMAGE_NAME=apache/airflow:latest AIRFLOW__CORE__FERNET_KEY='lmnHJcz5u4D8SPEeD4qwAf1TUk_yLXXnQfwlvQ8MXsU=' AIRFLOW_HOME=/opt/airflow/ -_AIRFLOW_WWW_USER_USERNAME=airflow -_AIRFLOW_WWW_USER_PASSWORD=airflow +AIRFLOW_USERNAME=airflow +AIRFLOW_PASSWORD=airflow AIRFLOW_UID=50000 diff --git a/plugins/schedule_loader.py b/plugins/schedule_loader.py index 610afa03..46e89045 100644 --- a/plugins/schedule_loader.py +++ b/plugins/schedule_loader.py @@ -1,4 +1,4 @@ -from airflow.models import Variable +from airflow.sdk import Variable from datetime import timedelta @@ -9,7 +9,7 @@ def get_dynamic_schedule(dag_id: str, default: str = "@daily") -> str | timedelt Se não houver schedule configurado, retorna o valor default (@daily). """ - schedules = Variable.get("dynamic_schedules", default_var={}, deserialize_json=True) + schedules = Variable.get("dynamic_schedules", default={}, deserialize_json=True) dag_schedule = schedules.get(dag_id) diff --git a/pyproject.toml b/pyproject.toml index 45682f5a..e7c4c427 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,19 +8,18 @@ readme = "README.md" [tool.poetry.dependencies] python = "~3.11" -apache-airflow = "2.8.1" -apache-airflow-providers-postgres = "5.14.0" -flask-session = "0.5.0" +apache-airflow = "3.2.2" +apache-airflow-providers-amazon = "9.29.0" +apache-airflow-providers-postgres = "6.7.0" +apache-airflow-providers-standard = "1.13.1" numpy = "1.26.4" -flask = "*" -dbt-core = "*" -dbt-postgres = "*" +dbt-core = ">=1.10,<1.11" +dbt-postgres = "1.10.0" pandas = "*" requests = "*" -sqlalchemy = "*" zeep = "*" imap-tools = "*" -astronomer-cosmos = "*" +astronomer-cosmos = "1.14.2" [tool.poetry.group.dev.dependencies] black = "*" @@ -157,9 +156,9 @@ capitalisation_policy = "lower" unwrap_wrapped_queries = true [tool.sqlfluff.templater.dbt] -project_dir = "./dbt/ipea" -profiles_dir = "./dbt/ipea" -profile = "ipea" +project_dir = "./dbt/minc" +profiles_dir = "./dbt/minc" +profile = "minc" target = "prod" defer_mode = true static_analysis = true diff --git a/requirements.txt b/requirements.txt index b6e8cb78..b3caaed0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,6 @@ -collate-sqllineage==1.6.0 -sqlparse==0.5 -astronomer-cosmos==1.9.0 -dbt-postgres==1.7.13 +astronomer-cosmos==1.14.2 +dbt-core>=1.10,<1.11 +dbt-postgres==1.10.0 imap-tools==1.10.0 zeep==4.3.1 openpyxl @@ -9,4 +8,6 @@ xlrd>=2.0.1 odfpy>=1.4.1 pyxlsb==1.0.10 python-calamine==0.6.2 -apache-airflow-providers-amazon==8.16.0 +apache-airflow-providers-amazon==9.29.0 +apache-airflow-providers-postgres==6.7.0 +apache-airflow-providers-standard==1.13.1 diff --git a/templates/siape/consultaDadosAfastamento.xml.j2 b/templates/siape/consultaDadosAfastamento.xml.j2 deleted file mode 100644 index 03ef212c..00000000 --- a/templates/siape/consultaDadosAfastamento.xml.j2 +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - {{ siglaSistema }} - {{ nomeSistema }} - {{ senha }} - {{ cpf }} - {{ codOrgao }} - {{ parmExistPag }} - {{ parmTipoVinculo }} - - - diff --git a/templates/siape/consultaDadosAfastamentoHistorico.xml.j2 b/templates/siape/consultaDadosAfastamentoHistorico.xml.j2 deleted file mode 100644 index 2552e80f..00000000 --- a/templates/siape/consultaDadosAfastamentoHistorico.xml.j2 +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - {{ siglaSistema }} - {{ nomeSistema }} - {{ senha }} - {{ cpf }} - {{ codOrgao }} - {{ parmExistPag }} - {{ parmTipoVinculo }} - {{ anoInicial }} - {{ mesInicial }} - {{ anoFinal }} - {{ mesFinal }} - - - \ No newline at end of file diff --git a/templates/siape/consultaDadosCurriculo.xml.j2 b/templates/siape/consultaDadosCurriculo.xml.j2 deleted file mode 100644 index 74937137..00000000 --- a/templates/siape/consultaDadosCurriculo.xml.j2 +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - {{ siglaSistema }} - {{ nomeSistema }} - {{ senha }} - {{ cpf }} - {{ codOrgao }} - {{ parmExistPag }} - {{ parmTipoVinculo }} - - - diff --git a/templates/siape/consultaDadosDependentes.xml.j2 b/templates/siape/consultaDadosDependentes.xml.j2 deleted file mode 100644 index 486ad749..00000000 --- a/templates/siape/consultaDadosDependentes.xml.j2 +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - {{ siglaSistema }} - {{ nomeSistema }} - {{ senha }} - {{ cpf }} - {{ codOrgao }} - {{ parmExistPag }} - {{ parmTipoVinculo }} - - - diff --git a/templates/siape/consultaDadosEscolares.xml.j2 b/templates/siape/consultaDadosEscolares.xml.j2 deleted file mode 100644 index 6b4409cd..00000000 --- a/templates/siape/consultaDadosEscolares.xml.j2 +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - {{ siglaSistema }} - {{ nomeSistema }} - {{ senha }} - {{ cpf }} - {{ codOrgao }} - {{ parmExistPag }} - {{ parmTipoVinculo }} - - - diff --git a/templates/siape/consultaDadosFinanceiros.xml.j2 b/templates/siape/consultaDadosFinanceiros.xml.j2 deleted file mode 100644 index 39d3ee25..00000000 --- a/templates/siape/consultaDadosFinanceiros.xml.j2 +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - {{ siglaSistema }} - {{ nomeSistema }} - {{ senha }} - {{ cpf }} - {{ codOrgao }} - {{ parmExistPag }} - {{ parmTipoVinculo }} - - - diff --git a/templates/siape/consultaDadosFuncionais.xml.j2 b/templates/siape/consultaDadosFuncionais.xml.j2 deleted file mode 100644 index 6d66114b..00000000 --- a/templates/siape/consultaDadosFuncionais.xml.j2 +++ /dev/null @@ -1,14 +0,0 @@ - - - - - {{ siglaSistema }} - {{ nomeSistema }} - {{ senha }} - {{ cpf }} - {{ codOrgao }} - {{ parmExistPag }} - {{ parmTipoVinculo }} - - - diff --git a/templates/siape/consultaDadosPA.xml.j2 b/templates/siape/consultaDadosPA.xml.j2 deleted file mode 100644 index 9c8e5983..00000000 --- a/templates/siape/consultaDadosPA.xml.j2 +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - {{ siglaSistema }} - {{ nomeSistema }} - {{ senha }} - {{ cpf }} - {{ codOrgao }} - {{ parmExistPag }} - {{ parmTipoVinculo }} - - - diff --git a/templates/siape/consultaDadosPessoais.xml.j2 b/templates/siape/consultaDadosPessoais.xml.j2 deleted file mode 100644 index d0e8c0e5..00000000 --- a/templates/siape/consultaDadosPessoais.xml.j2 +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - {{ siglaSistema }} - {{ nomeSistema }} - {{ senha }} - {{ cpf }} - {{ codOrgao }} - {{ parmExistPag }} - {{ parmTipoVinculo }} - - - diff --git a/templates/siape/consultaDadosUorg.xml.j2 b/templates/siape/consultaDadosUorg.xml.j2 deleted file mode 100644 index a9854c08..00000000 --- a/templates/siape/consultaDadosUorg.xml.j2 +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - {{ siglaSistema }} - {{ nomeSistema }} - {{ senha }} - {{ cpf }} - {{ codOrgao }} - {{ parmExistPag }} - {{ parmTipoVinculo }} - - - diff --git a/templates/siape/consultaPensoesInstituidas.xml.j2 b/templates/siape/consultaPensoesInstituidas.xml.j2 deleted file mode 100644 index d138d88c..00000000 --- a/templates/siape/consultaPensoesInstituidas.xml.j2 +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - {{ siglaSistema }} - {{ nomeSistema }} - {{ senha }} - {{ cpf }} - {{ codOrgao }} - {{ parmExistPag }} - {{ parmTipoVinculo }} - - - diff --git a/templates/siape/listaInformacoesAposentadoria.xml.j2 b/templates/siape/listaInformacoesAposentadoria.xml.j2 deleted file mode 100644 index 720dfbd1..00000000 --- a/templates/siape/listaInformacoesAposentadoria.xml.j2 +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - {{ siglaSistema }} - {{ nomeSistema }} - {{ senha }} - {{ cpf }} - {{ orgao }} - {{ matricula }} - - - diff --git a/templates/siape/listaServidores.xml.j2 b/templates/siape/listaServidores.xml.j2 deleted file mode 100644 index 0388e724..00000000 --- a/templates/siape/listaServidores.xml.j2 +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - {{ siglaSistema }} - {{ nomeSistema }} - {{ senha }} - {{ cpf }} - {{ codOrgao }} - {{ codUorg }} - - - diff --git a/templates/siape/listaUorgs.xml.j2 b/templates/siape/listaUorgs.xml.j2 deleted file mode 100644 index d17ea764..00000000 --- a/templates/siape/listaUorgs.xml.j2 +++ /dev/null @@ -1,13 +0,0 @@ - - - - - {{ siglaSistema }} - {{ nomeSistema }} - {{ senha }} - {{ cpf }} - {{ codOrgao }} - 00000000 - - - From 644fe7b411d0200b2980646de9a8b215d907831f Mon Sep 17 00:00:00 2001 From: arthrok Date: Thu, 18 Jun 2026 15:00:14 -0300 Subject: [PATCH 3/4] refactor: atualiza ci/cd para nova estrutura --- infra/airflow/airflow.cfg | 6 +++ infra/docker-compose.yml | 68 +++++++++++++++++++++++++++++++- infra/docker/superset/Dockerfile | 12 ++++++ 3 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 infra/airflow/airflow.cfg create mode 100644 infra/docker/superset/Dockerfile diff --git a/infra/airflow/airflow.cfg b/infra/airflow/airflow.cfg new file mode 100644 index 00000000..081853c1 --- /dev/null +++ b/infra/airflow/airflow.cfg @@ -0,0 +1,6 @@ +[core] +dags_folder = /opt/airflow/dags +plugins_folder = /opt/airflow/plugins + +[logging] +extra_path = /opt/airflow/helpers diff --git a/infra/docker-compose.yml b/infra/docker-compose.yml index e0d1cc82..2e60cb37 100644 --- a/infra/docker-compose.yml +++ b/infra/docker-compose.yml @@ -99,7 +99,6 @@ services: environment: <<: *airflow-common-env - # Postgres database postgres: image: postgres:15-alpine env_file: @@ -141,5 +140,72 @@ services: condition: service_healthy restart: always + superset: + build: + context: .. + dockerfile: infra/docker/superset/Dockerfile + environment: + SUPERSET_SECRET_KEY: 'supersetadmin' + SUPERSET_ENV: development + DATABASE_URL: postgresql+psycopg2://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/superset + ports: + - "8088:8088" + depends_on: + - postgres + restart: always + healthcheck: + test: ["CMD", "curl", "--fail", "http://localhost:8088/health"] + interval: 30s + timeout: 10s + retries: 3 + command: > + /bin/sh -c " + superset fab create-admin --username admin --firstname Admin --lastname User --email admin@superset.com --password admin && + superset db upgrade && + superset init && + superset run -p 8088 -h 0.0.0.0 --with-threads --reload --debugger + " + + minio: + image: minio/minio:RELEASE.2023-06-19T19-52-50Z + ports: + - "9000:9000" + - "9001:9001" + environment: + MINIO_ROOT_USER: ${MINIO_ACCESS_KEY:-minioadmin} + MINIO_ROOT_PASSWORD: ${MINIO_SECRET_KEY:-minioadmin} + command: server /data --console-address ":9001" + volumes: + - minio-data:/data + healthcheck: + test: + [ + "CMD-SHELL", + "mc alias set local http://127.0.0.1:9000 $${MINIO_ROOT_USER} $${MINIO_ROOT_PASSWORD} >/dev/null && mc ready local", + ] + interval: 10s + timeout: 5s + retries: 5 + restart: always + + # Creates the landing zone bucket on first start + minio-init: + image: minio/mc:latest + depends_on: + minio: + condition: service_healthy + entrypoint: > + /bin/sh -c " + mc alias set local http://minio:9000 $${MINIO_ACCESS_KEY:-minioadmin} $${MINIO_SECRET_KEY:-minioadmin} && + mc mb --ignore-existing local/$${RAW_STORAGE_CONTAINER:-data-lake-ipea} && + echo 'Bucket ready.' + " + environment: + MINIO_ACCESS_KEY: ${MINIO_ACCESS_KEY:-minioadmin} + MINIO_SECRET_KEY: ${MINIO_SECRET_KEY:-minioadmin} + RAW_STORAGE_CONTAINER: ${RAW_STORAGE_CONTAINER:-data-lake-ipea} + MINIO_BUCKET: ${MINIO_BUCKET:-${RAW_STORAGE_CONTAINER:-data-lake-ipea}} + volumes: postgres-db: + minio-data: diff --git a/infra/docker/superset/Dockerfile b/infra/docker/superset/Dockerfile new file mode 100644 index 00000000..3a301ac0 --- /dev/null +++ b/infra/docker/superset/Dockerfile @@ -0,0 +1,12 @@ +FROM apache/superset:latest + +USER root + +# Install PostgreSQL driver directly in the virtual environment site-packages +# This ensures the driver is available when Superset tries to connect to PostgreSQL +RUN /usr/local/bin/python -m pip install psycopg2-binary --target /app/.venv/lib/python3.10/site-packages/ + +# Install other useful database drivers for future use +RUN /usr/local/bin/python -m pip install pymysql --target /app/.venv/lib/python3.10/site-packages/ + +USER superset \ No newline at end of file From d8cdcc6cb8acf44cc19660fff31d16d98a37a686 Mon Sep 17 00:00:00 2001 From: arthrok Date: Thu, 18 Jun 2026 15:00:23 -0300 Subject: [PATCH 4/4] refactor: atualiza ci/cd para nova estrutura --- .github/workflows/main.yaml | 12 +++++++----- .gitignore | 1 - local.env | 5 ++++- requirements.txt | 1 + 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index f605387e..1f39b042 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -21,8 +21,8 @@ env: POETRY_CACHE_DIR: "/home/runner/.cache/poetry" DBT_PROJECT_DIR: "${{ github.workspace }}/dbt/minc" - IMAGE_REGISTRY_OWNER: govhub-br - IMAGE_NAME: ghcr.io/govhub-br/airflow-minc + IMAGE_REGISTRY: ghcr.io + IMAGE_NAME: ghcr.io/govhub-br/data-application-minc-airflow IMAGE_TAG_SHA: ${{ github.sha }} jobs: @@ -74,12 +74,13 @@ jobs: - uses: actions/checkout@v4 - uses: docker/setup-buildx-action@v3 - - name: Build + - name: Build Airflow uses: docker/build-push-action@v5 with: push: false context: . file: ./infra/docker/airflow/Dockerfile + target: airflow-prod cache-from: type=gha cache-to: type=gha,mode=max tags: | @@ -100,16 +101,17 @@ jobs: - name: Login GHCR uses: docker/login-action@v3 with: - registry: ghcr.io + registry: ${{ env.IMAGE_REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Build & Push + - name: Build & Push Airflow uses: docker/build-push-action@v5 with: push: true context: . file: ./infra/docker/airflow/Dockerfile + target: airflow-prod cache-from: type=gha cache-to: type=gha,mode=max tags: | diff --git a/.gitignore b/.gitignore index fb7cc556..0be1b37e 100644 --- a/.gitignore +++ b/.gitignore @@ -56,5 +56,4 @@ Thumbs.db # Airflow local files airflow.db -airflow.cfg webserver_config.py \ No newline at end of file diff --git a/local.env b/local.env index 0713ae25..9c56862e 100644 --- a/local.env +++ b/local.env @@ -22,7 +22,10 @@ POSTGRES_DB_DW=data_warehouse # <---------- MinIO ----------> -MINIO_ENDPOINT=minio:9000 +MINIO_ENDPOINT=http://minio:9000 MINIO_ACCESS_KEY=minioadmin MINIO_SECRET_KEY=minioadmin MINIO_BUCKET=data-lake-ipea +MINIO_REGION=us-east-1 +MINIO_URL_STYLE=path +MINIO_USE_SSL=false diff --git a/requirements.txt b/requirements.txt index b3caaed0..9ac110b1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,3 +11,4 @@ python-calamine==0.6.2 apache-airflow-providers-amazon==9.29.0 apache-airflow-providers-postgres==6.7.0 apache-airflow-providers-standard==1.13.1 +apache-airflow-providers-git==0.4.0 \ No newline at end of file