From 746fb5314ccc06acf61281c189600b3caae4d7c3 Mon Sep 17 00:00:00 2001 From: Pedro Castro Date: Thu, 28 Mar 2024 14:53:15 -0300 Subject: [PATCH] dbt: br_inep_censo_escolar.turma (#520) * dbt: br_inep_censo_escolar.turma * fix coercion * rename project name * remove tests --- .../br_inep_censo_escolar__turma.sql | 92 ++++++++ models/br_inep_censo_escolar/code/main.py | 114 ++++++++++ models/br_inep_censo_escolar/schema.yml | 204 ++++++++++++++++++ 3 files changed, 410 insertions(+) create mode 100644 models/br_inep_censo_escolar/br_inep_censo_escolar__turma.sql create mode 100644 models/br_inep_censo_escolar/code/main.py diff --git a/models/br_inep_censo_escolar/br_inep_censo_escolar__turma.sql b/models/br_inep_censo_escolar/br_inep_censo_escolar__turma.sql new file mode 100644 index 00000000..2d313fb8 --- /dev/null +++ b/models/br_inep_censo_escolar/br_inep_censo_escolar__turma.sql @@ -0,0 +1,92 @@ +{{ + config( + alias="turma", + schema="br_inep_censo_escolar", + partition_by={ + "field": "ano", + "data_type": "int64", + "range": {"start": 2009, "end": 2023, "interval": 1}, + }, + cluster_by="sigla_uf", + ) +}} +select + safe_cast(ano as int64) ano, + safe_cast(sigla_uf as string) sigla_uf, + safe_cast(id_municipio as string) id_municipio, + safe_cast(rede as string) rede, + safe_cast(id_escola as string) id_escola, + safe_cast(id_turma as string) id_turma, + safe_cast(etapa_ensino as string) etapa_ensino, + safe_cast(tipo_turma as string) tipo_turma, + safe_cast(hora_inicial as int64) hora_inicial, + safe_cast(minuto_inicial as int64) minuto_inicial, + safe_cast(dia_semana_domingo as int64) dia_semana_domingo, + safe_cast(dia_semana_segunda as int64) dia_semana_segunda, + safe_cast(dia_semana_terca as int64) dia_semana_terca, + safe_cast(dia_semana_quarta as int64) dia_semana_quarta, + safe_cast(dia_semana_quinta as int64) dia_semana_quinta, + safe_cast(dia_semana_sexta as int64) dia_semana_sexta, + safe_cast(dia_semana_sabado as int64) dia_semana_sabado, + safe_cast(numero_dias_atividade as int64) numero_dias_atividade, + safe_cast(numero_duracao_turma as int64) numero_duracao_turma, + safe_cast(tipo_atividade_1 as int64) tipo_atividade_1, + safe_cast(tipo_atividade_2 as int64) tipo_atividade_2, + safe_cast(tipo_atividade_3 as int64) tipo_atividade_3, + safe_cast(tipo_atividade_4 as int64) tipo_atividade_4, + safe_cast(tipo_atividade_5 as int64) tipo_atividade_5, + safe_cast(tipo_atividade_6 as int64) tipo_atividade_6, + safe_cast(id_curso_educacao_profissional as string) id_curso_educacao_profissional, + safe_cast(quantidade_matriculas as int64) quantidade_matriculas, + safe_cast(disciplina_lingua_portuguesa as int64) disciplina_lingua_portuguesa, + safe_cast(disciplina_educacao_fisica as int64) disciplina_educacao_fisica, + safe_cast(disciplina_artes as int64) disciplina_artes, + safe_cast(disciplina_lingua_ingles as int64) disciplina_lingua_ingles, + safe_cast(disciplina_lingua_espanhol as int64) disciplina_lingua_espanhol, + safe_cast(disciplina_lingua_frances as int64) disciplina_lingua_frances, + safe_cast(disciplina_lingua_outra as int64) disciplina_lingua_outra, + safe_cast(disciplina_libras as int64) disciplina_libras, + safe_cast(disciplina_lingua_indigena as int64) disciplina_lingua_indigena, + safe_cast(disciplina_matematica as int64) disciplina_matematica, + safe_cast(disciplina_ciencias as int64) disciplina_ciencias, + safe_cast(disciplina_fisica as int64) disciplina_fisica, + safe_cast(disciplina_quimica as int64) disciplina_quimica, + safe_cast(disciplina_biologia as int64) disciplina_biologia, + safe_cast(disciplina_historia as int64) disciplina_historia, + safe_cast(disciplina_geografia as int64) disciplina_geografia, + safe_cast(disciplina_sociologia as int64) disciplina_sociologia, + safe_cast(disciplina_filosofia as int64) disciplina_filosofia, + safe_cast(disciplina_estudos_sociais as int64) disciplina_estudos_sociais, + safe_cast(disciplina_informatica_comp as int64) disciplina_informatica_comp, + safe_cast(disciplina_ensino_religioso as int64) disciplina_ensino_religioso, + safe_cast(disciplina_profissionalizante as int64) disciplina_profissionalizante, + safe_cast(disciplina_pedagogicas as int64) disciplina_pedagogicas, + safe_cast(disciplina_outras as int64) disciplina_outras, + safe_cast(tipo_localizacao as string) tipo_localizacao, + safe_cast(tipo_categoria_escola_privada as string) tipo_categoria_escola_privada, + safe_cast(conveniada_poder_publico as int64) conveniada_poder_publico, + safe_cast(tipo_convenio_poder_publico as string) tipo_convenio_poder_publico, + safe_cast(mantenedora_privada_emp as int64) mantenedora_privada_emp, + safe_cast(mantenedora_privada_ong as int64) mantenedora_privada_ong, + safe_cast(mantenedora_privada_sind as int64) mantenedora_privada_sind, + safe_cast(mantenedora_privada_sist_s as int64) mantenedora_privada_sist_s, + safe_cast(mantenedora_privada_s_fins as int64) mantenedora_privada_s_fins, + safe_cast(tipo_regulamentacao as string) tipo_regulamentacao, + safe_cast(tipo_localizacao_diferenciada as string) tipo_localizacao_diferenciada, + safe_cast(educacao_indigena as int64) educacao_indigena, + safe_cast(braille as int64) braille, + safe_cast(recursos_baixa_visao as int64) recursos_baixa_visao, + safe_cast(processos_mentais as int64) processos_mentais, + safe_cast(orientacao_mobilidade as int64) orientacao_mobilidade, + safe_cast(sinais as int64) sinais, + safe_cast(comunicacao_alt_aument as int64) comunicacao_alt_aument, + safe_cast(enriquecimento_curricular as int64) enriquecimento_curricular, + safe_cast(soroban as int64) soroban, + safe_cast(informatica_acessivel as int64) informatica_acessivel, + safe_cast(port_escrita as int64) port_escrita, + safe_cast(autonomia_escolar as int64) autonomia_escolar, + safe_cast( + disciplina_atendimento_especiais as int64 + ) disciplina_atendimento_especiais, + safe_cast(disciplina_diver_socio_cultural as int64) disciplina_diver_socio_cultural, +from `basedosdados-staging.br_inep_censo_escolar_staging.turma` as t diff --git a/models/br_inep_censo_escolar/code/main.py b/models/br_inep_censo_escolar/code/main.py new file mode 100644 index 00000000..4c248ffe --- /dev/null +++ b/models/br_inep_censo_escolar/code/main.py @@ -0,0 +1,114 @@ +import os +import io +import requests +import basedosdados as bd +import pandas as pd +import numpy as np + +INPUT = os.path.join(os.getcwd(), "input") +OUTPUT = os.path.join(os.getcwd(), "output") + +os.makedirs(INPUT, exist_ok=True) +os.makedirs(OUTPUT, exist_ok=True) + +st = bd.Storage(dataset_id="br_inep_censo_escolar", table_id="turma") + +blobs = list(st.bucket.list_blobs(prefix=f"raw/br_inep_censo_escolar/turma/")) + +for blob in blobs: + filename = blob.name.split("/")[-1] + if filename.endswith(".CSV"): + blob.download_to_filename(filename=os.path.join(INPUT, filename)) + + +dfs = { + str(year): pd.read_csv(os.path.join(INPUT, f"TURMAS_{year}.CSV"), sep=";") + for year in range(2021, 2023 + 1) +} + + +arch = pd.read_csv( + io.StringIO( + requests.get( + "https://docs.google.com/spreadsheets/d/1qRf25hLSPYX-bSSyffk0DJP_C_mpCHngDY2x_kIohVo/export?format=csv", + timeout=10, + ).content.decode("utf-8") + ), + dtype=str, + na_values="", +) + +renames = { + i["original_name_2020"]: i["name"] + for i in arch.loc[ + (arch["name"] != "(deletado)") & (arch["original_name_2020"].notna()), + ][["original_name_2020", "name"]].to_dict("records") +} + +arch_cols = arch.loc[ + (arch["name"] != "(deletado)") & (arch["original_name_2020"].notna()), +]["name"].to_list() + + +dfs = { + year: df.rename( + columns={k: v for k, v in renames.items() if k in df.columns}, errors="raise" + ) + for year, df in dfs.items() +} + +dfs = {year: df[[i for i in arch_cols if i in df.columns]] for year, df in dfs.items()} + +df = pd.concat([i for _, i in dfs.items()]) + +del dfs # need memory + +all_cols = arch.loc[(arch["name"] != "(deletado)"),]["name"].to_list() + +cols_missing = list(set(all_cols) - set(df.columns)) + +for i in arch.loc[arch["bigquery_type"] == "STRING"]["name"]: + if i in df.columns: + # NOTE: fillna("") porque a coerção astype("Int64").astype("String") + # cria e ao salvar o csv, não é salvo como um valor + # vazio i.e "", ele salva como e isso é intepretado como uma string no BQ + df[i] = df[i].astype("Int64").astype("string").fillna("") # type: ignore + +for i in arch.loc[arch["bigquery_type"] == "INT64"]["name"]: + if i in df.columns: + df[i] = df[i].astype("Int64") + +for i in cols_missing: + df[i] = np.nan + +tb = bd.Table(dataset_id="br_inep_censo_escolar", table_id="turma") + +bq_cols = tb._get_columns_from_bq() + +partitions = [i["name"] for i in bq_cols["partition_columns"]] + +bd_dir = bd.read_sql( + "SELECT id_uf, sigla FROM `basedosdados.br_bd_diretorios_brasil.uf`", + billing_project_id="basedosdados-dev", +) + +df["sigla_uf"].unique() # type: ignore + +df["sigla_uf"] = df["sigla_uf"].replace( # type: ignore + {i["id_uf"]: i["sigla"] for i in bd_dir.to_dict("records")} # type: ignore +) + +df["sigla_uf"].unique() # type: ignore + +bq_storage_cols_order = [i["name"] for i in bq_cols["columns"]] + +for keys, df_split in df.groupby(partitions): + ano, sigla_uf = keys # type: ignore + path = os.path.join(OUTPUT, f"ano={ano}", f"sigla_uf={sigla_uf}") + os.makedirs(path, exist_ok=True) + df_split.drop(columns=["ano", "sigla_uf"])[bq_storage_cols_order].to_csv( # type: ignore + os.path.join(path, f"{ano}_{sigla_uf}.csv"), index=False + ) + + +tb.create(OUTPUT, if_table_exists="replace", if_storage_data_exists="replace") diff --git a/models/br_inep_censo_escolar/schema.yml b/models/br_inep_censo_escolar/schema.yml index 4a6f9509..3e599c66 100644 --- a/models/br_inep_censo_escolar/schema.yml +++ b/models/br_inep_censo_escolar/schema.yml @@ -1153,3 +1153,207 @@ models: - name: quantidade_turma_ead description: Número de Turmas da Educação Básica - Turno não aplicável para turmas semipresenciais ou de Educação a Distância (EAD) + - name: br_inep_censo_escolar__turma + description: A tabela contém dados que caracterizam as turmas de cada escola brasileira. + Entre os dados podemos encontrar as disciplinas feitas pela turma, o horário + de começo das aulas, o número de alunos da turma e o nível de ensino no qual + se encontra a turma. Há também vários outros aspectos mais específicos, como + se a turma passa por atividades complementares, em quais dias da semana ela + é ativa e se a turma conta com medidas de inclusão como aulas em libras e em + braille. + columns: + - name: ano + description: Ano do Censo + tests: + - relationships: + to: ref('br_bd_diretorios_data_tempo__ano') + field: ano.ano + - name: sigla_uf + description: Código da UF da escola + tests: + - relationships: + to: ref('br_bd_diretorios_brasil__uf') + field: sigla + - name: id_municipio + description: Código do Município da escola + tests: + - relationships: + to: ref('br_bd_diretorios_brasil__municipio') + field: id_municipio + - name: rede + description: Rede Escolar + tests: + - relationships: + to: ref('br_bd_diretorios_brasil__escola') + field: rede + - name: id_escola + description: Código da Escola + - name: id_turma + description: Código único da Turma + - name: etapa_ensino + description: Etapa de ensino da turma + - name: tipo_turma + description: Tipo de atendimento da turma (e.g. Unidade prisional, Classe + hospitalar) + - name: hora_inicial + description: Hora Inicial + - name: minuto_inicial + description: Minuto Inicial + - name: dia_semana_domingo + description: Dias da semana da Turma - Domingo + - name: dia_semana_segunda + description: Dias da semana da Turma - Segunda-Feira + - name: dia_semana_terca + description: Dias da semana da Turma - Terça-Feira + - name: dia_semana_quarta + description: Dias da semana da Turma - Quarta-Feira + - name: dia_semana_quinta + description: Dias da semana da Turma - Quinta_Feira + - name: dia_semana_sexta + description: Dias da semana da Turma - Sexta-Feira + - name: dia_semana_sabado + description: Dias da semana da Turma - Sábado + - name: numero_dias_atividade + description: Número de dias da semana onde são realizadas atividades da turma + - name: numero_duracao_turma + description: Duração de funcionamento da Turma - Minutos + - name: tipo_atividade_1 + description: Código do tipo de atividade complementar - Atividade 1 + - name: tipo_atividade_2 + description: Código do tipo de atividade complementar - Atividade 2 + - name: tipo_atividade_3 + description: Código do tipo de atividade complementar - Atividade 3 + - name: tipo_atividade_4 + description: Código do tipo de atividade complementar - Atividade 4 + - name: tipo_atividade_5 + description: Código do tipo de atividade complementar - Atividade 5 + - name: tipo_atividade_6 + description: Código do tipo de atividade complementar - Atividade 6 + - name: id_curso_educacao_profissional + description: Curso da Educação Profissional Técnica + - name: quantidade_matriculas + description: Número de matrículas na turma + - name: disciplina_lingua_portuguesa + description: Áreas do conhecimento/Componentes curriculares - Língua/ Literatura + Portuguesa + - name: disciplina_educacao_fisica + description: Áreas do conhecimento/Componentes curriculares - Educação Física + - name: disciplina_artes + description: Áreas do conhecimento/Componentes curriculares - Artes (Educação + Artística, Teatro, Dança, Música, Artes Plásticas e outras) + - name: disciplina_lingua_ingles + description: Áreas do conhecimento/Componentes curriculares - Língua/ Literatura + estrangeira - Inglês + - name: disciplina_lingua_espanhol + description: Áreas do conhecimento/Componentes curriculares - Língua/ Literatura + estrangeira - Espanhol + - name: disciplina_lingua_frances + description: Áreas do conhecimento/Componentes curriculares - Língua/ Literatura + estrangeira - Francês + - name: disciplina_lingua_outra + description: Áreas do conhecimento/Componentes curriculares - Língua/ Literatura + estrangeira - Outra + - name: disciplina_libras + description: Áreas do conhecimento/Componentes curriculares - Libras + - name: disciplina_lingua_indigena + description: Áreas do conhecimento/Componentes curriculares - Língua Indígena + - name: disciplina_matematica + description: Áreas do conhecimento/Componentes curriculares - Matemática + - name: disciplina_ciencias + description: Áreas do conhecimento/Componentes curriculares - Ciências + - name: disciplina_fisica + description: Áreas do conhecimento/Componentes curriculares - Física + - name: disciplina_quimica + description: Áreas do conhecimento/Componentes curriculares - Química + - name: disciplina_biologia + description: Áreas do conhecimento/Componentes curriculares - Biologia + - name: disciplina_historia + description: Áreas do conhecimento/Componentes curriculares - História + - name: disciplina_geografia + description: Áreas do conhecimento/Componentes curriculares - Geografia + - name: disciplina_sociologia + description: Áreas do conhecimento/Componentes curriculares - Sociologia + - name: disciplina_filosofia + description: Áreas do conhecimento/Componentes curriculares - Filosofia + - name: disciplina_estudos_sociais + description: Áreas do conhecimento/Componentes curriculares - Estudos Sociais + - name: disciplina_informatica_comp + description: Áreas do conhecimento/Componentes curriculares - Informática + / Computação + - name: disciplina_ensino_religioso + description: Áreas do conhecimento/Componentes curriculares - Ensino Religioso + - name: disciplina_profissionalizante + description: Áreas do conhecimento/Componentes curriculares - Disciplinas + dos cursos técnicos profissionais + - name: disciplina_pedagogicas + description: Áreas do conhecimento/Componentes curriculares - Disciplinas + pedagógicas + - name: disciplina_outras + description: Áreas do conhecimento/Componentes curriculares - Outras disciplinas + - name: tipo_localizacao + description: Localização (Escola) + - name: tipo_categoria_escola_privada + description: Categoria da escola privada + - name: conveniada_poder_publico + description: Conveniada com o poder público (Escola) + - name: tipo_convenio_poder_publico + description: Dependência do convênio com o poder público + - name: mantenedora_privada_emp + description: Mantenedora da escola privada - Empresa, grupo empresarial do + setor privado ou pessoa física + - name: mantenedora_privada_ong + description: Mantenedora da escola privada - Organização não governamental + (ONG) - internacional ou nacional. + - name: mantenedora_privada_sind + description: Mantenedora da escola privada - Sindicatos de trabalhadores ou + patronais, associações e cooperativas. + - name: mantenedora_privada_sist_s + description: Mantenedora da escola privada - Sistema S (Sesi, Senai, Sesc, + Outros) + - name: mantenedora_privada_s_fins + description: Mantenedora da escola privada - Instituições sem fins lucrativos + - name: tipo_regulamentacao + description: Regulamentação/Autorização no conselho ou órgão municipal, estadual + ou federal de educação + - name: tipo_localizacao_diferenciada + description: Localização diferenciada da escola + - name: educacao_indigena + description: Escola Indígena + - name: braille + description: Tipo de Atendimento Educacionl Especializado - Ensino do sistema + braille + - name: recursos_baixa_visao + description: Tipo de Atendimento Educacionl Especializado - Ensino do uso + de recursos ópticos e não ópticos + - name: processos_mentais + description: Tipo de Atendimento Educacionl Especializado - Estratégias para + o desenvolvimento de processos mentais + - name: orientacao_mobilidade + description: Tipo de Atendimento Educacionl Especializado - Ensino de técnicas + de orientação e mobilidade + - name: sinais + description: Tipo de Atendimento Educacionl Especializado - Ensino da Língua + Brasileira de Sinais - LIBRAS + - name: comunicacao_alt_aument + description: Tipo de Atendimento Educacionl Especializado - Ensino de uso + de Comunicação Alternativa Aumentada + - name: enriquecimento_curricular + description: Tipo de Atendimento Educacionl Especializado - Ensino de estratégias + para enriquecimento curricular + - name: soroban + description: Tipo de Atendimento Educacionl Especializado - Ensino de uso + do Soroban + - name: informatica_acessivel + description: Tipo de Atendimento Educacionl Especializado - Ensino da usabilidade + e da funcionalidade da informática acessível + - name: port_escrita + description: Tipo de Atendimento Educacionl Especializado - Ensino da Língua + Portuguesa na modalidade escrita + - name: autonomia_escolar + description: Tipo de Atendimento Educacionl Especializado - Ensino de estratégias + para autonomia no ambiente escolar + - name: disciplina_atendimento_especiais + description: Turma tem disciplinas voltadas ao atendimento às necessidades + educacionais específicas de alunos público-alvo + - name: disciplina_diver_socio_cultural + description: Turma tem disciplinas voltadas à diversidade sociocultural