From 3d565243051a37292264bae38e11b3b39a865b2e Mon Sep 17 00:00:00 2001 From: Gabriel Gazola Milan Date: Tue, 10 Dec 2024 12:59:38 -0300 Subject: [PATCH] feat: add dbt models --- queries/dbt_project.yml | 3 + .../adm_central_atendimento_1746/chamado.sql | 114 ++++++++++++++++++ .../chamado_pessoa.sql | 20 +++ .../adm_central_atendimento_1746/pessoa.sql | 74 ++++++++++++ .../adm_central_atendimento_1746/schema.yml | 100 +++++++++++++++ 5 files changed, 311 insertions(+) create mode 100644 queries/models/adm_central_atendimento_1746/chamado.sql create mode 100644 queries/models/adm_central_atendimento_1746/chamado_pessoa.sql create mode 100644 queries/models/adm_central_atendimento_1746/pessoa.sql create mode 100644 queries/models/adm_central_atendimento_1746/schema.yml diff --git a/queries/dbt_project.yml b/queries/dbt_project.yml index f4c3ea3..cc4a2b1 100644 --- a/queries/dbt_project.yml +++ b/queries/dbt_project.yml @@ -24,3 +24,6 @@ models: example: +materialized: view +schema: example + adm_central_atendimento_1746: + +materialized: view # Materialization type (view, table or incremental) + +schema: adm_central_atendimento_1746 # Overrides the default schema (defaults to what is set on profiles.yml) \ No newline at end of file diff --git a/queries/models/adm_central_atendimento_1746/chamado.sql b/queries/models/adm_central_atendimento_1746/chamado.sql new file mode 100644 index 0000000..92ae870 --- /dev/null +++ b/queries/models/adm_central_atendimento_1746/chamado.sql @@ -0,0 +1,114 @@ +{{ + config( + materialized='table', + unique_key='id_chamado', + partition_by={ + "field": "data_particao", + "data_type": "date", + "granularity": "month", + } + ) +}} + +WITH chamados AS ( + -- Elimina linhas duplicadas + SELECT * FROM ( + -- Alguns ds_endereco_numero vem no formato "15,17,19" e selecionamos o primeiro que aparece + SELECT + * EXCEPT(ds_endereco_numero), + CASE WHEN REGEXP_CONTAINS(CAST(ds_endereco_numero AS STRING), ",") THEN SPLIT(CAST(ds_endereco_numero AS STRING), ',')[SAFE_OFFSET(0)] ELSE ds_endereco_numero END AS ds_endereco_numero, + row_number() OVER (PARTITION BY id_chamado ORDER BY dt_fim DESC, data_particao DESC) AS ranking + FROM `rj-segovi.adm_central_atendimento_1746_staging.chamado` + + -- {% if is_incremental() %} + + -- -- this filter will only be applied on an incremental run + -- WHERE DATE(data_particao) > (SELECT max(DATE(data_particao)) FROM {{ this }}) + + -- {% endif %} + ) + WHERE ranking=1 +), + +enderecos_geolocalizados AS ( + -- Elimina linhas duplicadas + SELECT * FROM ( + SELECT + *, + row_number() OVER (PARTITION BY id_logradouro, SAFE_CAST(SAFE_CAST(numero_porta AS FLOAT64) AS STRING) ) AS ranking + FROM `rj-escritorio-dev.dados_mestres.enderecos_geolocalizados` + WHERE numero_porta IS NOT NULL + ) + WHERE ranking=1 +) + +SELECT DISTINCT + SAFE_CAST( + REGEXP_REPLACE(ch.id_chamado, r'\.0$', '') AS STRING + ) id_chamado, + SAFE_CAST( + REGEXP_REPLACE(ch.id_origem_ocorrencia, r'\.0$', '') AS STRING + ) id_origem_ocorrencia, + SAFE_CAST( + SAFE.PARSE_TIMESTAMP('%Y-%m-%d %H:%M:%S', ch.dt_inicio) AS DATETIME + ) AS data_inicio, + SAFE_CAST( + SAFE.PARSE_TIMESTAMP('%Y-%m-%d %H:%M:%S', ch.dt_fim) AS DATETIME + ) AS data_fim, + SAFE_CAST(REGEXP_REPLACE(ch.id_bairro, r'\.0$', '') AS STRING) id_bairro, + SAFE_CAST( + REGEXP_REPLACE(ch.id_territorialidade, r'\.0$', '') AS STRING + ) id_territorialidade, + SAFE_CAST( + REGEXP_REPLACE(ch.id_logradouro, r'\.0$', '') AS STRING + ) id_logradouro, + SAFE_CAST( + SAFE_CAST(ch.ds_endereco_numero AS FLOAT64) AS INT64 + ) numero_logradouro, + SAFE_CAST( + REGEXP_REPLACE(ch.id_unidade_organizacional, r'\.0$', '') AS STRING + ) id_unidade_organizacional, + SAFE_CAST( + REGEXP_REPLACE(ch.no_unidade_organizacional, r'\.0$', '') AS STRING + ) nome_unidade_organizacional, + SAFE_CAST( + REGEXP_REPLACE(ch.uo_mae, r'\.0$', '') AS STRING + ) id_unidade_organizacional_mae, + SAFE_CAST( + REGEXP_REPLACE(ch.fl_ouvidoria, r'\.0$', '') AS STRING + ) unidade_organizacional_ouvidoria, + SAFE_CAST(ch.no_categoria AS STRING) categoria, + SAFE_CAST(REGEXP_REPLACE(ch.id_tipo, r'\.0$', '') AS STRING) id_tipo, + SAFE_CAST(ch.no_tipo AS STRING) tipo, + SAFE_CAST( + REGEXP_REPLACE(ch.id_subtipo, r'\.0$', '') AS STRING + ) id_subtipo, + SAFE_CAST(ch.no_subtipo AS STRING) subtipo, + SAFE_CAST(ch.no_status AS STRING) status, + SAFE_CAST(geo.longitude AS FLOAT64) longitude, + SAFE_CAST(geo.latitude AS FLOAT64) latitude, + SAFE_CAST( + SAFE.PARSE_TIMESTAMP('%Y-%m-%d %H:%M:%S', ch.dt_alvo_finalizacao) AS DATETIME + ) AS data_alvo_finalizacao, + SAFE_CAST( + SAFE.PARSE_TIMESTAMP('%Y-%m-%d %H:%M:%S', ch.dt_alvo_diagnostico) AS DATETIME + ) AS data_alvo_diagnostico, + SAFE_CAST( + SAFE.PARSE_TIMESTAMP('%Y-%m-%d %H:%M:%S', ch.dt_real_diagnostico) AS DATETIME + ) AS data_real_diagnostico, + SAFE_CAST(ch.nu_prazo AS INT64) tempo_prazo, + SAFE_CAST( + REGEXP_REPLACE(ch.ic_prazo_unidade_tempo, r'\.0$', '') AS STRING + ) prazo_unidade, + SAFE_CAST(ch.ic_prazo_tipo AS STRING) prazo_tipo, + SAFE_CAST(ch.prazo AS STRING) dentro_prazo, + SAFE_CAST(ch.situacao AS STRING) situacao, + SAFE_CAST(ch.tipo_situacao AS STRING) tipo_situacao, + SAFE_CAST(ch.no_justificativa AS STRING) justificativa_status, + SAFE_CAST(ch.reclamacoes AS INT64) reclamacoes, + SAFE_CAST(ch.ds_chamado AS STRING) descricao, + SAFE_CAST(DATE_TRUNC(DATE(ch.data_particao), month) AS DATE) data_particao, + FROM chamados ch + LEFT JOIN enderecos_geolocalizados geo + ON SAFE_CAST(ch.id_logradouro AS FLOAT64) = CAST(geo.id_logradouro AS FLOAT64) + AND SAFE_CAST(ch.ds_endereco_numero AS FLOAT64) = cast(geo.numero_porta as FLOAT64) \ No newline at end of file diff --git a/queries/models/adm_central_atendimento_1746/chamado_pessoa.sql b/queries/models/adm_central_atendimento_1746/chamado_pessoa.sql new file mode 100644 index 0000000..c954809 --- /dev/null +++ b/queries/models/adm_central_atendimento_1746/chamado_pessoa.sql @@ -0,0 +1,20 @@ +{{ + config( + materialized='table', + unique_key='id_chamado', + partition_by={ + "field": "id_pessoa", + "data_type": "int64", + } + ) +}} + +SELECT + SAFE_CAST( + REGEXP_REPLACE(id_chamado, r'\.0$', '') AS STRING + ) id_chamado, + SAFE_CAST( + REGEXP_REPLACE(id_pessoa_fk, r'\.0$', '') AS INT64 + ) id_pessoa, +FROM `rj-segovi.adm_central_atendimento_1746_staging.chamado_pessoa` +WHERE id_pessoa_fk IS NOT NULL \ No newline at end of file diff --git a/queries/models/adm_central_atendimento_1746/pessoa.sql b/queries/models/adm_central_atendimento_1746/pessoa.sql new file mode 100644 index 0000000..012b48a --- /dev/null +++ b/queries/models/adm_central_atendimento_1746/pessoa.sql @@ -0,0 +1,74 @@ +{{ + config( + materialized='table', + unique_key='id_pessoa', + partition_by={ + "field": "cpf", + "data_type": "string", + } + ) +}} + +SELECT + SAFE_CAST( + REGEXP_REPLACE(id_pessoa, r'\.0$', '') AS INT64 + ) id_pessoa, + SAFE_CAST( + REGEXP_REPLACE(ds_cpf, r'\.0$', '') AS STRING + ) cpf, + SAFE_CAST( + REGEXP_REPLACE(no_pessoa, r'\.0$', '') AS STRING + ) nome, + SAFE_CAST( + REGEXP_REPLACE(ds_email, r'\.0$', '') AS STRING + ) email, + SAFE_CAST( + REGEXP_REPLACE(ds_endereco, r'\.0$', '') AS STRING + ) endereco, + SAFE_CAST( + SAFE_CAST(ds_endereco_numero AS FLOAT64) AS INT64 + ) endereco_numero, + SAFE_CAST( + REGEXP_REPLACE(ds_endereco_cep, r'\.0$', '') AS STRING + ) endereco_cep, + SAFE_CAST( + REGEXP_REPLACE(ds_endereco_complemento, r'\.0$', '') AS STRING + ) endereco_complemento, + SAFE_CAST( + REGEXP_REPLACE(ds_endereco_referencia, r'\.0$', '') AS STRING + ) endereco_referencia, + SAFE_CAST( + REGEXP_REPLACE(ds_telefone_1, r'\.0$', '') AS STRING + ) telefone_1, + SAFE_CAST( + REGEXP_REPLACE(ds_telefone_2, r'\.0$', '') AS STRING + ) telefone_2, + SAFE_CAST( + REGEXP_REPLACE(ds_telefone_3, r'\.0$', '') AS STRING + ) telefone_3, + SAFE_CAST( + SAFE.PARSE_TIMESTAMP('%Y-%m-%d', dt_nascimento) AS DATE -- TODO: review date format + ) data_nascimento, + SAFE_CAST( + REGEXP_REPLACE(ic_sexo, r'\.0$', '') AS STRING + ) sexo, + SAFE_CAST( + REGEXP_REPLACE(ds_identidade, r'\.0$', '') AS STRING + ) documento_identidade, + SAFE_CAST( + SAFE.PARSE_TIMESTAMP('%Y-%m-%d %H:%M:%S', dt_insercao) AS DATETIME -- TODO: review timestamp format + ) data_insercao, + SAFE_CAST( + SAFE.PARSE_TIMESTAMP('%Y-%m-%d %H:%M:%S', dt_atualizacao) AS DATETIME -- TODO: review timestamp format + ) data_atualizacao, + SAFE_CAST( + REGEXP_REPLACE(no_mae, r'\.0$', '') AS STRING + ) nome_mae, + SAFE_CAST( + REGEXP_REPLACE(id_escolaridade_fk, r'\.0$', '') AS INT64 + ) id_escolaridade, + SAFE_CAST( + REGEXP_REPLACE(ds_atividade_profissional, r'\.0$', '') AS STRING + ) atividade_profissional +from + tb_pessoa diff --git a/queries/models/adm_central_atendimento_1746/schema.yml b/queries/models/adm_central_atendimento_1746/schema.yml new file mode 100644 index 0000000..9ccb5f4 --- /dev/null +++ b/queries/models/adm_central_atendimento_1746/schema.yml @@ -0,0 +1,100 @@ +version: 2 +models : + - name: chamado + description: "**Descrição**: Chamados feitos ao 1746. São chamados desde março\ + \ de 2011, quando começou o projeto 1746.\r\n\r\n**Frequência de\ + \ atualização**: Diário\n**Cobertura temporal**: Março de 2011\n**Órgão gestor\ + \ dos dados**: SEGOVI\n**Publicado por**: Patricia Catandi\n**Publicado por\ + \ (email)**: patriciabcatandi@gmail.com\n" + columns: + - name: id_chamado + description: Identificador único do chamado no banco de dados. + - name: data_inicio + description: Data de abertura do chamado. Ocorre quando o operador registra + o chamado. + - name: data_fim + description: Data de fechamento do chamado. O chamado é fechado quando o pedido + é atendido ou quando se percebe que o pedido não pode ser atendido. + - name: id_bairro + description: Identificador único, no banco de dados, do bairro onde ocorreu + o fato que gerou o chamado. + - name: id_territorialidade + description: 'Identificador único, no banco de dados, da territorialidade + onde ocorreu o fato que gerou o chamado. Territorialidade é uma região da + cidade do Rio de Janeiro que tem com responsável um órgão especifico. Exemplo: + CDURP, que é responsável pela região do porto do Rio de Janeiro.' + - name: id_logradouro + description: Identificador único, no banco de dados, do logradouro onde ocorreu + o fato que gerou o chamado. + - name: numero_logradouro + description: Número da porta onde ocorreu o fato que gerou o chamado. + - name: id_unidade_organizacional + description: 'Identificador único, no banco de dados, do órgão que executa + o chamado. Por exemplo: identificador da COMLURB quando o chamado é relativo + a limpeza urbana.' + - name: nome_unidade_organizacional + description: 'Nome do órgão que executa a demanda. Por exemplo: COMLURB quando + a demanda é relativa a limpeza urbana.' + - name: unidade_organizadional_ouvidoria + description: Booleano indicando se o chamado do cidadão foi feita Ouvidoria + ou não. 1 caso sim, 0 caso não, + - name: categoria + description: 'Categoria do chamado. Exemplo: Serviço, informação, sugestão, + elogio, reclamação, crítica.' + - name: id_tipo + description: 'Identificador único, no banco de dados, do tipo do chamado. + Ex: Iluminação pública.' + - name: tipo + description: 'Nome do tipo do chamado. Ex: Iluminação pública.' + - name: id_subtipo + description: 'Identificador único, no banco de dados, do subtipo do chamado. + Ex: Reparo de lâmpada apagada.' + - name: subtipo + description: 'Nome do subtipo do chamado. Ex: Reparo de lâmpada apagada.' + - name: status + description: Status do chamado. Ex. Fechado com solução, aberto em andamento, + pendente etc. + - name: longitude + description: Longitude do lugar do evento que motivou o chamado. + - name: latitude + description: Latitude do lugar do evento que motivou o chamado. + - name: data_alvo_finalizacao + description: Data prevista para o atendimento do chamado. Caso prazo_tipo + seja D fica em branco até o diagnóstico ser feito. + - name: data_alvo_diagnostico + description: Data prevista para fazer o diagnóstico do serviço. Caso prazo_tipo + seja F esta data fica em branco. + - name: data_real_diagnostico + description: Data em que foi feito o diagnóstico do serviço. Caso prazo_tipo + seja F esta data fica em branco. + - name: tempo_prazo + description: Prazo para o serviço ser feito. Em dias ou horas após a abertura + do chamado. Caso haja diagnóstico o prazo conta após se fazer o diagnóstico. + - name: prazo_unidade + description: Unidade de tempo utilizada no prazo. Dias ou horas. D ou H. + - name: prazo_tipo + description: Diagnóstico ou finalização. D ou F. Indica se a chamada precisa + de diagnóstico ou não. Alguns serviços precisam de avaliação para serem + feitos, neste caso é feito o diagnóstico. Por exemplo, pode de árvore. Há + a necessidade de um engenheiro ambiental verificar a necessidade da poda + ou não. + - name: id_unidade_organizacional_mae + description: 'ID da unidade organizacional mãe do orgão que executa a demanda. + Por exemplo: "CVA - Coordenação de Vigilância de Alimentos" é quem executa + a demanda e obede a unidade organizacional mãe "IVISA-RIO - Instituto Municipal + de Vigilância Sanitária, de Zoonoses e de Inspeção Agropecuária". A coluna + se refere ao ID deste último.' + - name: reclamacoes + description: Quantidade de reclamações. + - name: situacao + description: Identifica se o chamado foi encerrado + - name: tipo_situacao + description: Indica o status atual do chamado entre as categorias Atendido, + Atendido parcialmente, Não atendido, Não constatado e Andamento + - name: dentro_prazo + description: Indica se a data alvo de finalização do chamado ainda está dentro + do prazo estipulado. + - name: justificativa_status + description: 'Justificativa que os órgãos usam ao definir o status. Exemplo: + SEM POSSIBILIDADE DE ATENDIMENTO - justificativa: Fora de área de atuação + do municipio' \ No newline at end of file