Consumo dos metadados¶
A biblioteca fornece describe_dataset, label, display_row e analytical_projection.
Elas funcionam offline com os recursos do wheel. Consultar metadados não abre um
lake nem baixa documentos. O contrato resolvido é 1.0.0; a versão editorial do
dicionário e a versão da regra analítica são informações separadas.
Definições e apresentação¶
import omnisus as sus
metadata = sus.describe_dataset("sim_obitos")
sexo = next(item for item in metadata["fields"] if item["field"]["name"] == "sexo")
print(sexo["field"]["logical_type"])
print(sexo["claims"])
print(metadata["metadata_hash"])
print(sus.display_row("sim_obitos", {"idade": "469", "sexo": "2"})) # sexo: "Feminino"
Cada chamada devolve dados independentes. fields contém documentos por coluna,
com referências resolvidas e estados de revisão; schema.fields preserva as
definições de autoria para consumidores de apresentação. Tipos legados são
descritivos: nenhum deles autoriza cast ou recodificação automática.
label (DataFrame) e display_row (uma linha) usam a mesma consulta: cada código
com mapa x-decode ganha o rótulo do dicionário, e um código que o mapa não
conhece fica sem rótulo (None). Datas, idades e horas saem como publicadas;
idade, sexo e datas comparáveis vêm só das projeções abaixo.
physical_type descreve o documento de origem, com comprimento desconhecido como
null. O tipo SQL efetivo vem de DESCRIBE no snapshot da consulta. Os valores
originais do lake continuam preservados.
Projeções para análise¶
As regras confirmam apenas os arquivos SIM/SIH/SINASC/SINAN/SIA identificados por escopo,
modalidade e SHA-256 em metadata["analytics"]["validated_sources"]. Outro arquivo,
mesmo da mesma UF/ano, não herda automaticamente a interpretação. A função não
consulta o lake: o chamador deve fornecer schema e identidades do mesmo snapshot,
verificando que as publicações representam todas as linhas dos escopos selecionados.
import omnisus as sus
target = "ducklake:./data/omnisus-v2.ducklake"
with sus.LakeReader(target, snapshot_id=5) as reader:
con = reader.connect()
schema = {row[0]: row[1] for row in con.sql("DESCRIBE lake.sim_obitos").fetchall()}
publications = [row for row in reader.publications()
if row["dataset"] == "sim_obitos" and row["active"] and row["managed"]]
contexts = [sus.SourceContext.from_publication(row) for row in publications]
projection = sus.analytical_projection("sim_obitos", observed_schema=schema, scopes=contexts)
print(projection.rule_version, projection.metadata_hash)
print(projection.unavailable)
Depois de verificar a cobertura do manifesto, o consumidor compõe uma subconsulta
com DerivedColumn.expression AS DerivedColumn.name. Os nomes de origem são
resolvidos/escapados pela biblioteca. Filtros de usuário continuam vinculados por
parâmetros na consulta do consumidor. As expressões executam em SQL nativo, sem
UDF Python por registro e sem criar views persistentes.
As colunas disponíveis são idade_anos_completos, idade_status, idade_quantidade,
idade_unidade, sexo_categoria, sexo_status, <campo>_data e <campo>_data_status.
Estados distinguem valid, missing, ignored, invalid e unsupported; nenhum
deles deve virar zero por conveniência. Numa data, valid quer dizer só que o texto é um
dia do calendário no formato do dicionário: a projeção não julga se a data é possível.
AMRR2401, processado em 2024-01, autoriza APACs em 2027-12-29 e
2029-12-29; BIRR2201 tem nascimento em 1892-11-05; o SIH tem nascimento em 1899-12-30.
A biblioteca não aplica limite de plausibilidade; a regra fica com a análise: compare com
a data do evento ou com o mês de processamento, e veja date_min/date_max em
sus.check_columns. SIM 400 significa zero anos completos com
precisão menor de um ano, não zero dias. Faixas etárias pertencem ao relatório.
idade_quantidade e idade_unidade (minute, hour, day, month ou year)
guardam a idade como a fonte a registrou: no SIM, 310 vira 10 month e 0 anos
completos. Em unidade year, a quantidade é a mesma de idade_anos_completos
(506 = 106 year). As duas colunas são nulas quando idade_status não é valid.
Em SIM 400 (menor de um ano, sem unidade registrada), idade_quantidade é 0 e
idade_unidade é year, como a fonte registrou.
No SINASC, idade_anos_completos interpreta idademae e se refere à mãe
(analytics.age.subject = "mother"). A regra não disponibiliza sexo materno:
sexo é do recém-nascido. A versão 1.0.0 cobre somente o DNRR2023 final auditado,
com domínio 1–65 anos e estados explícitos para valores fora desse suporte.
A regra do SIM 1.1.0 cobre RR/2021 a RR/2024 e SP/2024; a do SIH 1.2.0 cobre RR/2023-01,
SP/2024-01 a SP/2024-05 e SP/2025-01 a SP/2025-02. As regras do SIA 1.0.0 cobrem o BPA-I
de RR/2022-01 e RR/2024-01, a RAAS psicossocial de RR/2024-01 e a atenção domiciliar de
MA/2018-10 (x-analytics.validated_sources de cada dicionário).
Evidência e limites.
No SINAN (sinan_chagas, sinan_hanseniase, sinan_tuberculose),
idade_anos_completos interpreta nu_idade_n: um dígito de unidade (1 hora, 2 dia, 3 mês, 4 ano) seguido de três de
quantidade, então 4088 são 88 anos. A regra 1.0.0 cobre só os arquivos preliminares
auditados CHAGBR23, HANSBR26 e TUBEBR20.
Evidência.
Versão analítica solicitada e ausente gera erro. Colisão de nome derivado também.
Campo obrigatório ausente, dataset sem regra e contexto não confirmado retornam
indisponibilidade. Para reproduzir
resultados, fixar snapshot, versão do pacote/artefato, rule_version e
metadata_hash. Metadata hash deve ser conferido antes de reaplicar um preset.
A versão do pacote também fixa o conjunto de colunas da projeção: idade_quantidade
e idade_unidade, por exemplo, foram adicionadas nesta versão sem mudança de
rule_version.
Fontes, limitação e auditoria¶
O registro canônico está em src/omnisus/data/dicionarios/sources/registry.json.
Definições e revisões de campo
ficam nos YAMLs. Uma alteração de valor revisado exige atualizar sua evidência e
hash; referências inexistentes geram erro. Campo sem revisão não ganha aprovação
por estar no pacote.
A auditoria do snapshot 5, com SQL e agregados, está em
evidence/2026-09-14-contrato-analitico/. A referência SIH DT_INTER possui
grafia/formato inconsistente no manual; o contrato registra o conflito e restringe
a interpretação ao recorte conferido. Idades SIH fora do domínio explicitamente
suportado ficam unsupported, incluindo IDADE=999 sob unidade válida.
uv run --locked --extra dev python scripts/metadados/consultar.py --dataset sim_obitos --field sexo --json
uv run --locked --extra dev python scripts/metadados/consultar.py --dataset sih_aih_reduzida --field dt_inter --arrow
python scripts/metadados/auditar_contrato.py --target ducklake:./data/omnisus-v2.ducklake --snapshot-id 5 --out ./data/auditoria --acceptance-only
O script de consulta valida o documento e pode demonstrar transporte Arrow/Parquet
em tabela vazia. --metadata arquivo.json valida um exemplo arquivado. O exemplo
histórico 0.1.0-draft permanece legível; não é fonte de produção. Não há transporte
automático de metadados em toda consulta/exportação: para SQL/CSV guardar o JSON e a
identidade da regra no contrato da consulta.
Migração e limpeza¶
Use a interface pública em vez de importar o carregador interno. Dicionario
continua interno para ingestão/apresentação; Dicionario.arrow_schema foi removido,
pois não descrevia o lake e não tinha consumidor de produção. Helpers Polars de
transforms.codes usados apenas por testes também foram removidos.
x-normalization-hint substitui a antiga anotação x-transform: lpad_6 e não executa
normalização. A ingestão física e seu schema Arrow continuam implementados.
A ampliação da aplicabilidade a outros arquivos e a curadoria dos demais campos permanecem trabalho explícito. O contrato não declara validadas todas as bases.