Skip to content

fix(registry): mart per-anno su dataset multi-anno pubblicati con glob - #519

Merged
Gabrymi93 merged 1 commit into
mainfrom
fix/registry-mart-multi-year-glob
Oct 25, 2026
Merged

Gabrymi93 merged 1 commit into
mainfrom
fix/registry-mart-multi-year-glob

Conversation

@Gabrymi93

Copy link
Copy Markdown
Member

Sintesi

Il registry pubblicava i mart per-anno su dataset multi-anno con un path puntuale all'anno massimo e multi_file: false:

gs://dataciviclab-mart/energia_italia/terna_load_oraria/2025/mart_carico_annuale.parquet

I file mart sono uno per anno ({slug}/{year}/{table}.parquet), quindi i consumer che leggono location.path dal registry — in particolare dcl-mcp (gcs_query) — vedevano un solo anno invece della serie storica. Il clean non aveva il problema: clean_location globa con len(years) > 1.

Closes #518

Contesto collegato

Closes #518

Cosa cambia

  • Bug fix

  • Nuova funzionalità del motore

  • Nuovo plugin sorgente

  • Modifica contratto pubblico (dataset.yml, path output, schema parquet)

  • Refactor / performance

  • Documentazione

  • Dipendenze o CI

  • registry/paths.py: mart_location accetta years e, su più anni, produce il glob {slug}/*/{table}.parquet con multi_file: true (speculare a clean_location).

  • registry/builders.py: passa years=sorted(manifest.years) a mart_location.

  • registry/schemas/registry.schema.json: documenta il significato di location.multi_file.

  • Test: contratto multi-anno aggiornato + caso mono-anno (path puntuale invariato).

Impatto su contratti pubblici

  • Struttura dataset.yml (nuovo campo, cambio obbligatorietà)
  • Path output (nuovo layer, cambio percorso artifact)
  • Schema parquet (nuova colonna, rename, cambio tipo)
  • CLI o MCP tool (nuovo comando, cambio parametro)
  • API pubblica del toolkit (firma funzione, classe, eccezione)

Cambia il valore di marts[].location in registry/registry.json per i mart per-anno su dataset multi-anno: da path puntuale (.../{max_year}/{table}.parquet) a glob (.../*/{table}.parquet) con multi_file: true. Nessun campo nuovo, nessun rename; il campo multi_file esisteva già (default true in lab_connectors.registry.models).

Downstream: il consumer dcl-mcp supporta già i glob (dcl_mcp/gcs/resolver.py::to_read_paths usa gs:// + httpfs quando il path contiene *), quindi non richiede modifiche. Verificati anche toolkit/core/support.py (ricostruisce il path dal pattern, non da location.path) e infra/lab-dashboard / infra/data-explorer (usano solo la location clean). [ ] dataset-incubator — [x] docs/ (schema aggiornato nel repo)

Verifica

pytest -q                        # 1325 passed, 1 skipped
pytest tests/test_registry_builder.py tests/test_registry.py tests/test_registry_ops.py tests/test_cli_registry.py
ruff check .
mypy toolkit/
  • pytest -m core passa (intera suite verde)
  • ruff check . passa
  • mypy toolkit/ passa
  • Modificato o aggiunto test con marker appropriato (contract)

Verifica end-to-end (registry energia-italia, dry-run + lettura del glob da GCS):

mart per-anno multi-anno  → gs://dataciviclab-mart/energia_italia/terna_load_oraria/*/mart_carico_annuale.parquet  (multi_file=true)
  lettura → 12 righe, 2019-2025 (total+market)   # prima: 1 anno
mart per-anno mono-anno   → gs://dataciviclab-mart/energia_italia/terna_storage_accumuli/2024/mart_storage_*.parquet  (multi_file=false)
mart multi-anno (years:)  → gs://dataciviclab-mart/test/my_dataset/mart_trend.parquet  (multi_file=false)

Regressione: test_multi_year_mart_flat e test_path_contract_year_layout falliscono senza il fix e passano con il fix.

Checklist PR

Note per chi revisiona

Tipo: root fix
Problema reale: il builder deriva la location dei mart per-anno da un solo anno (max), mentre il clean usa un glob multi-anno: due regole diverse per lo stesso artifact.
Contratto riusato/sostituito: riusato il pattern di clean_location (glob + multi_file) invece di aggiungere un caso speciale nel consumer.
Codice rimosso o duplicazione eliminata: rimosso l'import locale ridondante di get_bucket in clean_location.
Test aggiunti: 1 nuovo (mart per-anno mono-anno), 2 aggiornati al nuovo contratto.
Rischio residuo: i registry.json dei repo produttori vanno rigenerati (il builder gira in CI post-merge) perché il path cambi; fino ad allora il catalogo continua a esporre un solo anno. Il blob glob richiede httpfs lato consumer — dcl-mcp lo fa già, altri consumer esterni che usassero il path con read_parquet esatto andrebbero verificati.
Follow-up obbligatorio: rigenerare i registry dei repo con mart per-anno multi-anno (694 mart in 8 repo) tramite la CI post-merge già esistente; nessuna azione manuale prevista.
  • Il glob {slug}/*/{table}.parquet è robusto anche se un mart non esiste per tutti gli anni dichiarati: DuckDB legge i file presenti.
  • Fix secondario incluso: prima un mart che non esisteva per l'anno massimo produceva un path inesistente; il glob lo evita.

I mart per-anno sono un file per anno ({slug}/{year}/{table}.parquet), ma il
builder pubblicava una location puntuale all'anno massimo con multi_file=false:
i consumer del registry (dcl-mcp gcs_query) vedevano un solo anno invece della
serie storica. Il clean non aveva il problema: clean_location globa quando
len(years) > 1.

- paths.py: mart_location accetta years e, su più anni, produce il glob
  {slug}/*/{table}.parquet con multi_file=true (speculare a clean_location)
- builders.py: passa years a mart_location
- schema: documenta il significato di location.multi_file
- test: contratto multi-anno aggiornato + caso mono-anno invariato

Closes #518
@Gabrymi93
Gabrymi93 merged commit d419d2e into main Oct 25, 2026
3 checks passed
@Gabrymi93
Gabrymi93 deleted the fix/registry-mart-multi-year-glob branch October 25, 2026 22:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] registry: mart per-anno su dataset multi-anno espongono solo l'ultimo anno (location puntuale invece di glob)

1 participant