Files
fn_registry/python/functions/pipelines/profile_bq_dataset.md
T
egutierrez 5a4f82cf76 chore: auto-commit (26 archivos)
- python/functions/bigquery/bq_auth.md
- python/functions/bigquery/bq_load_from_file.md
- python/functions/bigquery/bq_load_from_gcs.md
- python/functions/bigquery/client.py
- python/functions/bigquery/queries.py
- python/functions/datascience/__init__.py
- python/functions/datascience/decode_qr_image.py
- python/functions/datascience/load_bq_table_to_duckdb.md
- python/functions/datascience/load_bq_table_to_duckdb.py
- python/functions/pipelines/profile_bq_table.md
- ...

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-02 19:00:13 +02:00

8.7 KiB

name, kind, lang, domain, purity, version, signature, description, tags, uses_functions, uses_types, returns, returns_optional, error_type, imports, tested, tests, test_file_path, file_path, params, output
name kind lang domain purity version signature description tags uses_functions uses_types returns returns_optional error_type imports tested tests test_file_path file_path params output
profile_bq_dataset pipeline py pipelines impure 1.1.0 def profile_bq_dataset(project_id: str, dataset: str, tables: list = None, include_views: bool = False, sample_frac: float = None, max_rows: int = 0, pseudonymize_cols: dict = None, report_dir: str = "reports", duckdb_path: str = "", keep_duckdb: bool = True, min_inclusion: float = 0.9, emit_pdf: bool = True, run_llm: bool = False) -> dict EDA one-shot de un dataset BigQuery ENTERO con descubrimiento cross-tabla: materializa CADA tabla del dataset (COMPLETA por defecto; muestreo opt-in con sample_frac; seudonimizacion PII por tabla, LOPDGDD/RGPD) en UN MISMO DuckDB compartido con load_bq_table_to_duckdb, lo perfila entero con profile_database (perfiles por tabla + relaciones FK inter-tabla por containment + join graph Mermaid + report markdown/JSON + PDF movil), y construye el diccionario de columnas del dataset con build_column_dictionary. Es el analogo BigQuery de profile_database a nivel de dataset, resuelto por composicion estricta (list_bq_dataset_tables -> load_bq_table_to_duckdb x N -> profile_database -> build_column_dictionary) sin duplicar descubrimiento, perfilado ni inferencia de relaciones. Es el hazme un EDA de este dataset BigQuery entero y descubre como se relacionan sus tablas, en una sola llamada.
eda
bigquery
relations
launcher
list_bq_dataset_tables_py_datascience
load_bq_table_to_duckdb_py_datascience
profile_database_py_pipelines
build_column_dictionary_py_datascience
false error_go_core
false
python/functions/pipelines/profile_bq_dataset.py
name desc
project_id Proyecto GCP (facturacion + primer segmento del FQN). Ej: 'autingo-159109'.
name desc
dataset Dataset BigQuery a perfilar entero. Ej: 'customer_marts'.
name desc
tables Lista de NOMBRES de tabla del dataset. None (DEFAULT) = todas las del dataset (filtradas por include_views).
name desc
include_views Si True incluye las VIEW ademas de las BASE TABLE cuando tables=None. Default False (solo BASE TABLE, coherente con profile_database que salta las VIEWs).
name desc
sample_frac None (DEFAULT) = FULL, perfila TODAS las filas de cada tabla. Un float en (0,1) activa el muestreo opt-in por tabla (`WHERE rand() < frac`).
name desc
max_rows Tope duro de filas por tabla (LIMIT). 0 (DEFAULT) = sin tope. Se aplica a cada tabla materializada.
name desc
pseudonymize_cols Dict {"tabla": ["col1", "col2"]} de columnas PII a seudonimizar (hash) por tabla ANTES de materializar (LOPDGDD/RGPD [POL-MMNSEG-001-1.0]). Preserva nulos y cardinalidad.
name desc
report_dir Directorio de salida de los reports + del DuckDB compartido por defecto. Default 'reports' (artefacto local gitignored). Se crea si no existe.
name desc
duckdb_path Ruta del DuckDB compartido donde se materializan todas las tablas. Vacio (DEFAULT) = report_dir/eda_bq_<dataset>.duckdb (se limpia si ya existia).
name desc
keep_duckdb Si True (DEFAULT) conserva el DuckDB materializado: es el artefacto explorable post-EDA (notebook Jupyter, joins ad-hoc). Con False se borra al terminar.
name desc
min_inclusion Umbral de inclusion (0-1) para emitir una FK candidata cross-tabla (se pasa a profile_database -> infer_fk_containment_duckdb). Default 0.9.
name desc
emit_pdf Si True (DEFAULT) emite el PDF movil DB-level (resumen de tablas + relaciones FK + join graph). Se pasa a profile_database.
name desc
run_llm Si True (default False) activa la capa LLM interpretativa por tabla (se pasa a profile_database -> profile_table): una llamada LLM por tabla sobre el perfil agregado, nunca filas crudas.
dict dict-no-throw. En exito {status:'ok', project_id, dataset, n_tables_loaded, n_tables_profiled, tables_skipped:[...], errors:[...], duckdb_path, db_profile:<DatabaseProfile con tables[resumen], table_profiles[completos], fk_candidates, join_graph{nodes,edges,mermaid,hubs}>, column_dictionary:{entries,pii_columns} (sin markdown), report_md_path, report_json_path, report_pdf_path, dict_md_path, dict_json_path}. En error {status:'error', error, stage}.

Ejemplo

from pipelines.profile_bq_dataset import profile_bq_dataset

# FULL por defecto: EDA del dataset ENTERO (todas las tablas, todas las filas),
# con FK cross-tabla + join graph + diccionario de columnas. El DuckDB compartido
# queda en reports/eda_bq_customer_marts.duckdb para seguir explorando.
r = profile_bq_dataset("autingo-159109", "customer_marts")
print(r["n_tables_loaded"], "tablas materializadas,", r["n_tables_profiled"], "perfiladas")
print("FKs:", [f"{fk['from_table']}.{fk['from_col']}->{fk['to_table']}.{fk['to_col']}"
               for fk in r["db_profile"]["fk_candidates"]])
print(r["report_md_path"]); print(r["report_pdf_path"]); print(r["dict_md_path"])
print("DuckDB explorable:", r["duckdb_path"])

# Dataset con tablas enormes: muestreo opt-in + PII seudonimizada por tabla.
r = profile_bq_dataset(
    "autingo-159109",
    "customer_marts",
    sample_frac=0.05,
    pseudonymize_cols={
        "customer_profile": ["document_number", "full_name", "email", "phone"],
    },
)

Cuando usarla

Cuando pidan un EDA de un DATASET BigQuery entero y no solo de una tabla: quieres el perfil de todas sus tablas MAS su esquema relacional (que tabla referencia a cual, con que cardinalidad) descubierto cross-tabla en una sola llamada. Es el escalon a nivel de dataset sobre profile_bq_table (una tabla) y el adaptador BigQuery de profile_database (una base DuckDB). Usala al recibir un dataset BigQuery desconocido, para documentar un data mart, para descubrir el star schema (las tablas hub del join graph) o antes de escribir joins sin tener el modelo declarado. Para datasets con tablas enormes, pasa sample_frac o max_rows y dejalo declarado en el report.

Gotchas

  • Impura: requiere ADC de BigQuery configurado (Application Default Credentials). Si el ADC del usuario lleva un quota project ajeno, load_bq_table_to_duckdb / list_bq_dataset_tables aplican creds.with_quota_project(None) para evitar el 403 USER_PROJECT_DENIED — remitido a los gotchas de esas funciones.
  • Coste de traer un DATASET entero: FULL por defecto materializa TODAS las filas de CADA tabla a RAM (via BigQuery Storage Read API/Arrow) antes de volcar al DuckDB compartido. Un dataset con varias tablas de millones de filas puede costar en tiempo, bytes escaneados de BigQuery y GBs de RAM/disco. Acota con sample_frac in (0,1) (muestreo opt-in por tabla) o max_rows (tope duro por tabla). Si por limite de recursos no cabe el total, dilo explicito en el report con el maximo que si se cargo.
  • El DuckDB compartido puede ocupar GBs: todas las tablas del dataset viven en un MISMO archivo (necesario para que la inferencia de FK opere cross-tabla). Con keep_duckdb=True (default) queda en disco como artefacto explorable; pasa keep_duckdb=False para borrarlo al terminar. Con duckdb_path explicito la ruta se respeta; el path por defecto se limpia al inicio para no mezclar tablas de corridas anteriores.
  • FK por containment es una HEURISTICA (falsos positivos/negativos posibles) y profile_database SALTA los pares de FK hacia tablas con mas de 200k filas (el lado caro del INTERSECT): esas relaciones quedan sin evaluar. Es un mapa de partida del esquema, no un DDL autoritativo.
  • Vistas excluidas por defecto (include_views=False, coherente con profile_database que salta VIEWs — perfilarlas infla n_tables y multiplica FK falsas). Pasa include_views=True solo si necesitas perfilarlas como si fueran tablas materializadas.
  • Seudonimiza PII con pseudonymize_cols (dict por tabla) para cumplir LOPDGDD/ RGPD [POL-MMNSEG-001-1.0] ANTES de escribir a disco: nombres, DNI/NIE, email, telefono, direccion, IDs de cliente, IBAN, etc. Sin seudonimizar, el DuckDB compartido + los reports contienen datos personales reales.
  • Tolera fallos por tabla: si una carga falla, se anota en errors[] + tables_skipped[] y el pipeline sigue con las demas; n_tables_profiled cuenta solo las perfiladas con exito. Revisa errors para saber que quedo fuera.
  • Escribe a report_dir (default 'reports', artefacto local gitignored): el report DB-level de profile_database (markdown + JSON + PDF si emit_pdf) MAS el diccionario de columnas (..._dict.md + ..._dict.json).

Capability growth log

  • v1.1.0 (2026-07-02) — añade run_llm (passthrough a profile_database -> profile_table: una llamada LLM por tabla sobre el perfil agregado). Default False, sin breaking changes.