Files
fn_registry/dev/issues/0175-eda-relational-fk-inference-views.md
T
Egutierrez 7ac69ab4fb feat(eda): series temporales + rigor anti-data-mining + PDF movil + /eda + benchmark issues
Bloque del grupo eda (sesion ausente EDA-benchmark):
- 8 funciones nuevas: adf_kpss_stationarity, acf_pacf, stl_decompose, to_returns,
  fdr_correction, suggest_reexpression, exploratory_caveats, render_eda_pdf
- integracion: profile_table (run_series, emit_pdf), association_matrix (FDR Benjamini-Hochberg),
  render_eda_markdown (secciones series/reexpresion/caveats)
- slash commands /eda y /capitulos
- issues 0173-0177: mejoras del /eda derivadas del benchmark sobre 12 datasets reales
  (outlier_pct x100, periodo estacional, FK inference, render models, tipos id-like)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 03:34:01 +02:00

5.9 KiB
Raw Blame History

id, title, status, type, domain, scope, priority, depends, blocks, related, created, updated, tags
id title status type domain scope priority depends blocks related created updated tags
0175 EDA relational: precisión de FK inference (falsos positivos) + filtrar VIEWs + test ATTACH pendiente bugfix
registry-quality
registry-only alta
0173
0174
0176
0177
2026-06-29 2026-06-29
eda
datascience
infer_fk_containment_duckdb
build_join_graph
profile_database
duckdb
benchmark

0175 — EDA relational: precisión de FK inference + filtrar VIEWs

Contexto

El benchmark /eda (29/06/2026, temp/eda_benchmark/EVALUATION.md) confirmó que la inferencia de claves foráneas a nivel de base es inútil por falsos positivos masivos y que las VISTAS se perfilan como tablas base. El join graph resultante necesita filtrado manual para ser legible.

Hallazgos cubiertos:

Hallazgo Severidad Evidencia del benchmark
H3 — FK inference por contención: 10-20× falsos positivos crítico chinook 111 candidatas vs ~11 reales; sakila 565 vs ~30. Casos absurdos: InvoiceLine.Quantity→Album.AlbumId, Genre.GenreId→{Album,Artist,Customer,…}
H5 — VIEWs perfiladas como tablas base alto sakila n_tables=21 incluye 5 VISTAS (customer_list, film_list 5462 filas, staff_list, sales_by_store, sales_by_film_category) + film_text (FTS, 0 filas)
H10 — coste relacional gastado en computar FK falsas medio sakila 31.82s: la mayoría en INTERSECT de los 565 pares candidatos, casi todos falsos
H14 — bug sqlite_master does not exist tras ATTACH (ya parcheado, falta test) bajo (resuelto) _run.log: profile_database falló con Catalog Error: src.sqlite_master; re-run posterior ok

Causa raíz (verificada en código, READ-ONLY)

  • python/functions/datascience/infer_fk_containment_duckdb.py:217-285 emite una FK candidata si inclusion(A⊆B) ≥ min_inclusion y B "parece clave" (unicidad ≥0.95). No usa el nombre de la columna, que es la señal más fuerte de FK (AlbumId→Album.AlbumId), ni excluye columnas no-clave (cantidades, importes) como ORIGEN. Enteros pequeños (GenreId 1..25) están contenidos en casi todo → ruido.
  • python/functions/pipelines/profile_database.py:155-159 lista tablas con duckdb_list_tables sin filtrar table_type → perfila VIEWs y tablas FTS como base (H5), lo que infla el universo de pares y multiplica las FK falsas (relaciona H10).
  • H10 es el mismo cambio que H3: filtrar candidatos por nombre antes del INTERSECT reduce pares (más rápido) y falsos positivos (más preciso) a la vez.

Tareas

  1. H3+H10 — señal de nombre en infer_fk_containment_duckdb.py:217-285: antes de lanzar el INTERSECT, exigir coincidencia/patrón de nombre entre origen y destino (from_col casa con to_table/to_col, patrón <X>Id → <X>.<X>Id; case-insensitive). Excluir como ORIGEN columnas claramente no-clave (cantidades, importes, flags) por heurística de nombre/tipo. Esto poda el O(tablas²×columnas²) y elimina la mayoría de los falsos positivos. Validar mejor la cardinalidad (los 1:1 imposibles del benchmark).
  2. H5 — filtrar VIEWs antes de perfilar e inferir FK: filtrar table_type='BASE TABLE' vía information_schema.tables / duckdb_tables(). Decidir (a confirmar al implementar) si el filtro va como flag nuevo en duckdb_list_tables (infra, reutilizable) o en profile_database.py tras listar. Preferir el flag en duckdb_list_tables si no rompe consumidores.
  3. H3 — propagar al join graph: verificar que build_join_graph.py recibe la lista ya filtrada y que el diagrama Mermaid resultante es legible (sin nodos VIEW ni aristas espurias).
  4. H14 — test de regresión: añadir test (en profile_database_test.py o infer_fk_containment_duckdb_test.py) que haga ATTACH de una base SQLite pequeña en DuckDB y perfile, confirmando que se usa information_schema/duckdb_tables() y nunca sqlite_master. (A confirmar: localizar la función que hace el ATTACH —probablemente summarize_table_duckdb.py o una primitiva infra duckdb_*— para cubrirla.)
  5. Tests: casos sintéticos con tablas que tengan columnas tipo XId (FK real) y columnas de cantidad contenidas en claves (falso positivo) → confirmar que solo emite las reales.

Definition of Done

Escenario Tipo Comando / evidencia Resultado esperado
Golden: FK reales sin ruido e2e re-correr profile_database sobre chinook ~11 FK candidatas (no 111); incluyen Album.ArtistId→Artist.ArtistId, Invoice.CustomerId→Customer.CustomerId; NO incluyen InvoiceLine.Quantity→Album.AlbumId
Edge: VIEWs excluidas e2e re-correr profile_database sobre sakila n_tables cuenta solo BASE TABLE (sin customer_list/film_list/…); FK candidatas ≪ 565
Edge: cantidad vs clave unit infer_fk_containment_duckdb_test.py con columna Quantity contenida en una clave NO emite FK desde Quantity
Error: ATTACH SQLite unit test de regresión ATTACH SQLite→DuckDB perfila sin sqlite_master does not exist; usa information_schema
Rendimiento (H10) e2e medir duración de profile_database sobre sakila menor que el baseline 31.82s (menos INTERSECT)
Mecánica ./fn run infer_fk_containment_duckdb_py_datascience, ./fn run profile_database_py_pipelines; fn index tests verdes; índice limpio

Re-correr el benchmark sobre chinook y sakila y confirmar que las FK reales son distinguibles del ruido y que las VIEWs no se cuentan como tablas.

Notas

Issue derivado de temp/eda_benchmark/EDA_ISSUES.md. Tres síntomas (H3/H5/H10) con un núcleo común: la capa de inferencia de relaciones inter-tabla. Atacarlos juntos en una rama; filtrar VIEWs reduce el universo de pares y filtrar candidatos por nombre arregla precisión y velocidad a la vez. H14 ya está parcheado en producción; este issue solo añade el test de regresión que faltaba. Hermanos: 0173, 0174, 0176, 0177.