Pular para o conteúdo principal

Contratos de dados

Três estruturas circulam por todo o sistema. Elas são dicionários Python simples — sem ORM, sem classes — o que mantém o pipeline barato e serializável.

1. O dicionário da persona​

Produzido por gen_00_pessoa.build_persona() e enriquecido pelos demais geradores.

CampoTipoOrigem
idstr (UUID5)determinístico a partir do índice e da semente
idxintposição na geração
nome_completo, nome_social, ultimo_sobrenomestr/Nonecatálogos MALE_FIRST_NAMES, FEMALE_FIRST_NAMES, SURNAMES
data_nascimentostr ISOpirâmide etária fictícia + âncora temporal
sexo"masculino" | "feminino"Bernoulli(0,5)
nacionalidadestrcatálogo
cidade_nascimento, uf_nascimento, cidade_residenciastrGeographyEngine
classe_social"A" | "B1" | "B2" | "C1" | "C2" | "D_E"SocioeconomicEngine.sample_class
estado_civilstrperfil por faixa etária
esta_vivobooltábua de mortalidade
data_obitostr ISO | Nonesó quando esta_vivo é falso
education"fundamental" | "medio" | "superior" | "pos"logit ordinal
setor_empregadostrcatálogo de setores
ancestry, ancestry_pctsstr, dict[str, float]priors de ancestralidade (Dirichlet)
cor_olhos, cor_cabelo, pele, mao_dominantestrGeneticEngine
tipo_sanguineo, fator_rhstrPunnett ABO/Rh
altura, pesofloatmid-parent de Galton + IMC log-normal
criminaldictCriminalEngine.criminal_process_series()

Campos acrescentados em tempo de execução por geradores posteriores (exemplos): pai_id, mae_id, geracao, tem_doenca_grave, impactos_saude, tem_antecedente_criminal.

:::tip Projeção para a tabela pessoa as_pessoa_row(persona) recorta apenas as colunas que existem no DDL do hub. Campos auxiliares (como criminal ou ancestry_pcts) nunca chegam ao banco — eles existem só para coordenar os geradores. :::

2. O dataset em memória​

Dataset = dict[str, list[dict[str, Any]]]

Um mapa nome_da_tabela → lista de linhas, onde cada linha é um dicionário cujas chaves são nomes de coluna do DDL. Regras do contrato:

  • as chaves de tabela devem existir no schema PostgreSQL (sql/schema/*.sql);
  • valores são tipos JSON-serializáveis; datas são str em ISO-8601;
  • None representa NULL;
  • dict/list aninhados são serializados como JSON pelo exportador e pelo carregador;
  • toda tabela satélite carrega pessoa_id apontando para pessoa.id.
{
"pessoa": [{"id": "…", "nome_completo": "…", "data_nascimento": "1988-04-12", …}],
"doenca_pessoa": [{"id": "…", "pessoa_id": "…", "doenca_id": "…", "data_diagnostico": "2019-07-02"}],
…
}

3. O contrato do gerador​

Todo módulo gen_XX_*.py expõe:

def generate(
personas: list[dict],
seed: int = 7,
today: date | None = None,
# apenas 07_residencia, 11_juridico, 13_viagens e 16_timeline:
existing_tables: dict[str, list[dict]] | None = None,
) -> dict[str, list[dict]]:
...

Detalhes e checklist em Contrato dos geradores.

4. O relatório de validação​

Devolvido por validate_dataset(dataset, today=None):

ChaveTipoSignificado
passedboolnenhuma violação encontrada
violation_count / critical_violationsinttotal de violações (deduplicadas)
violationslist[dict]cada item tem domain, rule e, quando aplicável, person_id, table, value
violations_by_ruledict[str, int]contagem por regra
domain_consistencydict[str, float]percentual de consistência por domínio validado
overall_consistency_pctfloatmédia dos percentuais por domínio
row_countsdict[str, int]linhas por tabela
{
"passed": false,
"violation_count": 2,
"violations": [
{"domain": "genealogia", "rule": "parent_at_least_14", "person_id": "…", "parent_id": "…"},
{"domain": "temporal", "rule": "end_before_start", "table": "contrato_trabalho", "start": "2021-03-01", "end": "2020-12-01"}
],
"domain_consistency": {"genealogia": 99.5, "temporal": 99.5, "financas": 100.0,
"saude": 100.0, "juridico": 100.0, "social": 100.0},
"overall_consistency_pct": 99.83
}

5. Convenções de identificadores​

ConvençãoExemplo
UUID de linha derivado de chave estáveluuid5(NAMESPACE_URL, f"doenca-pessoa-{pessoa_id}-{i}")
Catálogos compartilhados têm ID próprio e sem pessoa_idhospital, empresa, banco, partido
Tabelas de junção usam PK compostapessoa_habilidade(pessoa_id, habilidade_id)
Datas sempre como str ISO"2026-01-01"
Valores monetários em float BRL4231.57