feat: add LLM SQL query assistant and dataset sampler

- ask.py: Python script to query Base dos Dados via natural language using Gemini,
  generates and executes DuckDB SQL from Portuguese questions
- ask/ (Rust): CLI companion for the SQL query assistant with system prompt
- sample_datasets.py: samples parquet files from S3 into a local DuckDB for exploration
- sample_datasets/ (Rust): CLI for dataset sampling
- context/: LLM context bundle (schemas, join keys, file tree) for query generation
This commit is contained in:
2026-03-28 11:23:51 +01:00
parent 6801db427e
commit b5d84e3556
13 changed files with 156445 additions and 0 deletions

228
context/join_keys.md Normal file
View File

@@ -0,0 +1,228 @@
# Join Key Reference
This file documents the most important columns for joining tables across datasets.
Generated by `schema_compiler.py` from `schemas.json`.
## Geographic Keys
### `cep` — 14 tables
Brazilian postal code (CEP). br_bd_diretorios_brasil.cep has the reference mapping.
**Sample tables (10 of 14):**
`br_bd_diretorios_brasil.cep`, `br_bd_diretorios_brasil.empresa`, `br_cvm_administradores_carteira.pessoa_juridica`, `br_ibge_censo_2022.cadastro_enderecos`, `br_inep_censo_educacao_superior.ies`, `br_me_cnpj.estabelecimentos`, `br_me_rais.microdados_estabelecimentos`, `br_mg_belohorizonte_smfa_iptu.iptu`, `br_ms_cnes.estabelecimento`, `br_rf_cafir.imoveis_rurais`
### `id_distrito` — 11 tables
IBGE district code.
**Sample tables (10 of 11):**
`br_bd_diretorios_brasil.distrito_1991`, `br_bd_diretorios_brasil.distrito_2000`, `br_bd_diretorios_brasil.distrito_2010`, `br_bd_diretorios_brasil.setor_censitario_2010`, `br_bd_diretorios_brasil.setor_censitario_2022`, `br_geobr_mapas.limite_vizinhanca`, `br_geobr_mapas.setor_censitario_2010`, `br_ibge_censo_2022.cadastro_enderecos`, `br_ibge_censo_demografico.microdados_domicilio_1980`, `br_ibge_censo_demografico.microdados_domicilio_2000`
### `id_mesorregiao` — 7 tables
IBGE mesoregion code.
**Sample tables (7 of 7):**
`br_bd_diretorios_brasil.municipio`, `br_bd_diretorios_brasil.setor_censitario_2022`, `br_geobr_mapas.mesorregiao`, `br_ibge_censo_demografico.microdados_domicilio_2000`, `br_ibge_censo_demografico.microdados_domicilio_2010`, `br_ibge_censo_demografico.microdados_pessoa_2000`, `br_ibge_censo_demografico.microdados_pessoa_2010`
### `id_microrregiao` — 7 tables
IBGE microregion code.
**Sample tables (7 of 7):**
`br_bd_diretorios_brasil.municipio`, `br_bd_diretorios_brasil.setor_censitario_2022`, `br_geobr_mapas.microrregiao`, `br_ibge_censo_demografico.microdados_domicilio_2000`, `br_ibge_censo_demografico.microdados_domicilio_2010`, `br_ibge_censo_demografico.microdados_pessoa_2000`, `br_ibge_censo_demografico.microdados_pessoa_2010`
### `id_municipio` — 195 tables
7-digit IBGE municipality code stored as VARCHAR. Present in 195+ tables. br_bd_diretorios_brasil.municipio is the canonical reference table.
**Sample tables (10 of 195):**
`br_anatel_banda_larga_fixa.densidade_municipio`, `br_anatel_banda_larga_fixa.microdados`, `br_anatel_indice_brasileiro_conectividade.municipio`, `br_anp_precos_combustiveis.microdados`, `br_ans_beneficiario.informacao_consolidada`, `br_bcb_estban.agencia`, `br_bcb_estban.municipio`, `br_bcb_sicor.recurso_publico_complemento_operacao`, `br_bd_diretorios_brasil.cep`, `br_bd_diretorios_brasil.distrito_1991`
**Example JOIN:**
```sql
SELECT m.nome AS municipio, m.sigla_uf, t.densidade
FROM br_anatel_banda_larga_fixa.densidade_municipio t
JOIN br_bd_diretorios_brasil.municipio m ON t.id_municipio = m.id_municipio
WHERE t.ano = 2022
ORDER BY t.densidade DESC
LIMIT 20
```
### `id_municipio_tse` — 23 tables
TSE (Electoral Court) municipality code — used in electoral datasets.
**Sample tables (10 of 23):**
`br_bd_diretorios_brasil.municipio`, `br_tse_eleicoes.candidatos`, `br_tse_eleicoes.despesas_candidato`, `br_tse_eleicoes.detalhes_votacao_municipio`, `br_tse_eleicoes.detalhes_votacao_municipio_zona`, `br_tse_eleicoes.detalhes_votacao_secao`, `br_tse_eleicoes.partidos`, `br_tse_eleicoes.perfil_eleitorado_local_votacao`, `br_tse_eleicoes.perfil_eleitorado_municipio_zona`, `br_tse_eleicoes.perfil_eleitorado_secao`
### `id_regiao` — 13 tables
IBGE macro-region code (15).
**Sample tables (10 of 13):**
`br_bd_diretorios_brasil.setor_censitario_2022`, `br_geobr_mapas.regiao`, `br_geobr_mapas.sede_municipal`, `br_ibge_censo_demografico.microdados_domicilio_2000`, `br_ibge_censo_demografico.microdados_domicilio_2010`, `br_ibge_censo_demografico.microdados_pessoa_2010`, `br_ibge_pnad.microdados_compatibilizados_domicilio`, `br_ibge_pnad.microdados_compatibilizados_pessoa`, `br_inep_saeb.aluno_ef_2ano`, `br_inep_saeb.aluno_ef_5ano`
### `id_setor_censitario` — 27 tables
15-digit IBGE census tract code.
**Sample tables (10 of 27):**
`br_bd_diretorios_brasil.setor_censitario_2010`, `br_bd_diretorios_brasil.setor_censitario_2022`, `br_geobr_mapas.setor_censitario_2010`, `br_ibge_censo_2022.cadastro_enderecos`, `br_ibge_censo_2022.setor_censitario`, `br_ibge_censo_demografico.setor_censitario_alfabetizacao_homens_mulheres_2010`, `br_ibge_censo_demografico.setor_censitario_alfabetizacao_total_2010`, `br_ibge_censo_demografico.setor_censitario_basico_2010`, `br_ibge_censo_demografico.setor_censitario_domicilio_caracteristicas_gerais_2010`, `br_ibge_censo_demografico.setor_censitario_domicilio_moradores_2010`
### `id_subdistrito` — 7 tables
IBGE subdistrict code.
**Sample tables (7 of 7):**
`br_bd_diretorios_brasil.setor_censitario_2010`, `br_bd_diretorios_brasil.setor_censitario_2022`, `br_geobr_mapas.limite_vizinhanca`, `br_geobr_mapas.setor_censitario_2010`, `br_ibge_censo_2022.cadastro_enderecos`, `br_ibge_censo_demografico.microdados_domicilio_2000`, `br_ibge_censo_demografico.microdados_pessoa_2000`
### `id_uf` — 22 tables
2-digit IBGE UF code (e.g. "35" = São Paulo).
**Sample tables (10 of 22):**
`br_bd_diretorios_brasil.municipio`, `br_bd_diretorios_brasil.setor_censitario_2022`, `br_bd_diretorios_brasil.uf`, `br_geobr_mapas.limite_vizinhanca`, `br_geobr_mapas.mesorregiao`, `br_geobr_mapas.microrregiao`, `br_geobr_mapas.regiao_imediata`, `br_geobr_mapas.regiao_intermediaria`, `br_geobr_mapas.saude`, `br_geobr_mapas.sede_municipal`
### `nome_municipio` — 8 tables
Municipality name as string. Prefer id_municipio for joins to avoid encoding issues.
**Sample tables (8 of 8):**
`br_bd_diretorios_brasil.cep`, `br_bd_diretorios_brasil.setor_censitario_2010`, `br_bd_diretorios_brasil.setor_censitario_2022`, `br_geobr_mapas.limite_vizinhanca`, `br_geobr_mapas.sede_municipal`, `br_geobr_mapas.setor_censitario_2010`, `br_geobr_mapas.terra_indigena`, `br_poder360_pesquisas.microdados`
### `sigla_uf` — 245 tables
2-letter state abbreviation (e.g. "SP", "RJ"). Present in 245+ tables.
**Sample tables (10 of 245):**
`br_anatel_banda_larga_fixa.densidade_municipio`, `br_anatel_banda_larga_fixa.densidade_uf`, `br_anatel_banda_larga_fixa.microdados`, `br_anatel_indice_brasileiro_conectividade.municipio`, `br_anp_precos_combustiveis.microdados`, `br_ans_beneficiario.informacao_consolidada`, `br_bcb_estban.agencia`, `br_bcb_estban.municipio`, `br_bcb_sicor.operacao`, `br_bd_diretorios_brasil.cep`
**Example JOIN:**
```sql
SELECT u.nome AS estado, COUNT(*) AS obitos
FROM br_ms_sim.microdados s
JOIN br_bd_diretorios_brasil.uf u ON s.sigla_uf = u.sigla_uf
WHERE s.ano = 2020
GROUP BY 1
ORDER BY 2 DESC
```
## Temporal Keys
### `ano` — 261 tables
Year as INT. Present in 261+ tables. Always filter by ano when possible.
**Sample tables (10 of 261):**
`br_anatel_banda_larga_fixa.densidade_brasil`, `br_anatel_banda_larga_fixa.densidade_municipio`, `br_anatel_banda_larga_fixa.densidade_uf`, `br_anatel_banda_larga_fixa.microdados`, `br_anatel_indice_brasileiro_conectividade.municipio`, `br_anp_precos_combustiveis.microdados`, `br_ans_beneficiario.informacao_consolidada`, `br_bcb_estban.agencia`, `br_bcb_estban.municipio`, `br_bcb_sicor.liberacao`
**Example JOIN:**
```sql
SELECT a.ano, a.id_municipio, a.densidade AS banda_larga, b.ideb
FROM br_anatel_banda_larga_fixa.densidade_municipio a
JOIN br_inep_ideb.municipio b
ON a.id_municipio = b.id_municipio AND a.ano = b.ano
WHERE a.ano BETWEEN 2015 AND 2021
```
### `data` — 19 tables
Full DATE column. Used in microdata tables for event-level records.
**Sample tables (10 of 19):**
`br_camara_dados_abertos.deputado_profissao`, `br_camara_dados_abertos.proposicao_microdados`, `br_camara_dados_abertos.votacao`, `br_camara_dados_abertos.votacao_objeto`, `br_camara_dados_abertos.votacao_parlamentar`, `br_camara_dados_abertos.votacao_proposicao`, `br_inmet_bdmep.microdados`, `br_me_cnpj.empresas`, `br_me_cnpj.estabelecimentos`, `br_me_cnpj.socios`
### `mes` — 94 tables
Month as INT (112). Present in 94+ tables. Use together with ano.
**Sample tables (10 of 94):**
`br_anatel_banda_larga_fixa.densidade_brasil`, `br_anatel_banda_larga_fixa.densidade_municipio`, `br_anatel_banda_larga_fixa.densidade_uf`, `br_anatel_banda_larga_fixa.microdados`, `br_ans_beneficiario.informacao_consolidada`, `br_bcb_estban.agencia`, `br_bcb_estban.municipio`, `br_bcb_sicor.liberacao`, `br_bcb_sicor.saldo`, `br_cgu_beneficios_cidadao.auxilio_emergencial`
### `semestre` — 1 tables
Semester (12). Used in PNAD Contínua and similar surveys.
**Sample tables (1 of 1):**
`br_mec_sisu.microdados`
### `trimestre` — 3 tables
Quarter (14). Used in quarterly economic datasets.
**Sample tables (3 of 3):**
`br_ibge_pnadc.educacao`, `br_ibge_pnadc.microdados`, `br_ibge_pnadc.rendimentos_outras_fontes`
### `year` — 21 tables
Year (English name) — used in international/world datasets.
**Sample tables (10 of 21):**
`br_trase_supply_chain.beef`, `br_trase_supply_chain.soy_beans`, `br_trase_supply_chain.soy_beans_crushing_facilities`, `br_trase_supply_chain.soy_beans_refining_facilities`, `us_harvard_ned.parliamentary_elections`, `us_harvard_ned.presidential_elections`, `world_iea_timss.home_context_grade_4`, `world_iea_timss.school_context_grade_4`, `world_iea_timss.school_context_grade_8`, `world_iea_timss.student_achievement_grade_4`
## Business Identity Keys
### `cbo_2002` — 6 tables
Brazilian Occupation Classification 2002 code. Joins labor market datasets.
**Sample tables (6 of 6):**
`br_bd_diretorios_brasil.cbo_2002`, `br_me_caged.microdados_movimentacao`, `br_me_caged.microdados_movimentacao_excluida`, `br_me_caged.microdados_movimentacao_fora_prazo`, `br_me_rais.microdados_vinculos`, `br_ms_cnes.profissional`
### `cnae_2_subclasse` — 6 tables
CNAE 2.0 economic activity subclass code. 7-digit, joins RAIS, CAGED, CNPJ data.
**Sample tables (6 of 6):**
`br_me_caged.microdados_movimentacao`, `br_me_caged.microdados_movimentacao_excluida`, `br_me_caged.microdados_movimentacao_fora_prazo`, `br_me_rais.microdados_estabelecimentos`, `br_me_rais.microdados_vinculos`, `br_rf_cno.cnaes`
### `cnpj` — 8 tables
14-digit Brazilian company tax ID.
**Sample tables (8 of 8):**
`br_anatel_banda_larga_fixa.microdados`, `br_ans_beneficiario.informacao_consolidada`, `br_bcb_sicor.recurso_publico_mutuario`, `br_bd_diretorios_brasil.empresa`, `br_cvm_administradores_carteira.pessoa_juridica`, `br_cvm_administradores_carteira.responsavel`, `br_me_cnpj.estabelecimentos`, `br_trase_supply_chain.soy_beans_crushing_facilities`
**Example JOIN:**
```sql
SELECT e.razao_social, SUM(t.acessos) AS total_acessos
FROM br_anatel_banda_larga_fixa.microdados t
JOIN br_bd_diretorios_brasil.empresa e ON t.cnpj = e.cnpj
WHERE t.ano = 2023
GROUP BY 1
ORDER BY 2 DESC
LIMIT 10
```
### `cnpj_basico` — 10 tables
First 8 digits of CNPJ (company base code, without branch).
**Sample tables (10 of 10):**
`br_bcb_estban.agencia`, `br_bcb_estban.municipio`, `br_bcb_sicor.recurso_publico_cooperado`, `br_bcb_sicor.recurso_publico_mutuario`, `br_bcb_sicor.recurso_publico_propriedade`, `br_bd_diretorios_brasil.empresa`, `br_me_cnpj.empresas`, `br_me_cnpj.estabelecimentos`, `br_me_cnpj.simples`, `br_me_cnpj.socios`
### `cpf` — 14 tables
11-digit Brazilian individual tax ID (CPF). Often masked in public datasets.
**Sample tables (10 of 14):**
`br_bcb_sicor.recurso_publico_cooperado`, `br_bcb_sicor.recurso_publico_mutuario`, `br_bcb_sicor.recurso_publico_propriedade`, `br_camara_dados_abertos.despesa`, `br_cgu_servidores_executivo_federal.afastamentos`, `br_cgu_servidores_executivo_federal.cadastro_aposentados`, `br_cgu_servidores_executivo_federal.cadastro_pensionistas`, `br_cgu_servidores_executivo_federal.cadastro_reserva_reforma_militares`, `br_cgu_servidores_executivo_federal.cadastro_servidores`, `br_cgu_servidores_executivo_federal.observacoes`
### `id_escola` — 14 tables
INEP school code. Joins censo_escolar and ENEM escola tables.
**Sample tables (10 of 14):**
`br_bd_diretorios_brasil.escola`, `br_geobr_mapas.escola`, `br_inep_avaliacao_alfabetizacao.alunos`, `br_inep_censo_escolar.escola`, `br_inep_censo_escolar.turma`, `br_inep_ideb.escola`, `br_inep_indicador_nivel_socioeconomico.escola`, `br_inep_indicadores_educacionais.escola`, `br_inep_saeb.aluno_ef_2ano`, `br_inep_saeb.aluno_ef_5ano`
### `id_estabelecimento_cnes` — 18 tables
CNES health establishment code. Joins SUS health datasets.
**Sample tables (10 of 18):**
`br_ms_cnes.dados_complementares`, `br_ms_cnes.equipamento`, `br_ms_cnes.equipe`, `br_ms_cnes.estabelecimento`, `br_ms_cnes.estabelecimento_ensino`, `br_ms_cnes.estabelecimento_filantropico`, `br_ms_cnes.gestao_metas`, `br_ms_cnes.habilitacao`, `br_ms_cnes.incentivos`, `br_ms_cnes.leito`
### `id_inscricao` — 27 tables
ENEM registration/enrollment ID. Joins ENEM tables across years.
**Sample tables (10 of 27):**
`br_inep_enem.microdados`, `br_inep_enem.questionario_socioeconomico_1998`, `br_inep_enem.questionario_socioeconomico_1999`, `br_inep_enem.questionario_socioeconomico_2000`, `br_inep_enem.questionario_socioeconomico_2001`, `br_inep_enem.questionario_socioeconomico_2002`, `br_inep_enem.questionario_socioeconomico_2003`, `br_inep_enem.questionario_socioeconomico_2004`, `br_inep_enem.questionario_socioeconomico_2005`, `br_inep_enem.questionario_socioeconomico_2006`
**Example JOIN:**
```sql
-- id_inscricao joins ENEM microdata across years
SELECT a.ano, a.nota_matematica, b.nota_matematica AS nota_ano_anterior
FROM br_inep_enem.microdados a
JOIN br_inep_enem.microdados b
ON a.id_inscricao = b.id_inscricao AND b.ano = a.ano - 1
WHERE a.ano = 2023
```
### `id_orgao` — 14 tables
Federal government organ code. Used in CGU budget/contract datasets.
**Sample tables (10 of 14):**
`br_camara_dados_abertos.evento_orgao`, `br_camara_dados_abertos.legislatura_mesa`, `br_camara_dados_abertos.licitacao_pedido`, `br_camara_dados_abertos.orgao`, `br_camara_dados_abertos.orgao_deputado`, `br_camara_dados_abertos.votacao`, `br_cgu_licitacao_contrato.contrato_apostilamento`, `br_cgu_licitacao_contrato.contrato_compra`, `br_cgu_licitacao_contrato.contrato_item`, `br_cgu_licitacao_contrato.contrato_termo_aditivo`
### `id_unidade_gestora` — 13 tables
Federal budget management unit code.
**Sample tables (10 of 13):**
`br_cgu_licitacao_contrato.contrato_apostilamento`, `br_cgu_licitacao_contrato.contrato_compra`, `br_cgu_licitacao_contrato.licitacao`, `br_cgu_licitacao_contrato.licitacao_empenho`, `br_cgu_licitacao_contrato.licitacao_item`, `br_cgu_licitacao_contrato.licitacao_participante`, `world_wb_mides.empenho`, `world_wb_mides.licitacao`, `world_wb_mides.licitacao_item`, `world_wb_mides.licitacao_participante`