Skip to main content

log_message + QA de merges

Propósito

Patrón de logging con timestamp + elapsed y verificaciones mínimas para merges (filas pre/post, columnas en común, cobertura). Este esquema aparece en tus scripts de producción y acelera diagnóstico de cuellos de botella y uniones problemáticas.

log_message (timestamp + elapsed)

import time

def log_message(msg, t0=None):
now = time.time()
stamp = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(now))
dt = f' | elapsed: {now - t0:.2f}s' if t0 else ''
print(f'[{stamp}] {msg}{dt}')

Usado para marcar etapas (extracción, transformaciones, sampleo, merge, compute, guardado).

QA de merges (pre/post filas + columnas en común)

t_merge = time.time()

common_cols = left.columns.intersection(right.columns).tolist()
log_message(f"Merging on columns: {common_cols}") # guarda evidencia de claves reales
rows_before = len(left)

out = left.merge(
right[common_cols + ['ALGUNA_COL_EXTRA']], # evita arrastrar columnas inútiles
on=common_cols, how='left', validate='m:1' # elige validate según cardinalidad esperada
)

rows_after = len(out)
if rows_after != rows_before:
log_message("WARNING: row count changed after merge", t_merge)
else:
log_message("Merge completed", t_merge)

Este patrón ya figura en tus notas (comparando filas y logueando columnas de unión).

Cuando no alcanza contar filas

  • indicator=True para medir anti-joins (_merge=='left_only' o 'right_only').
  • validate (p.ej., m:1, 1:1) obliga la cardinalidad esperada (falla temprano).
  • Reportar tasa de cobertura: out['_merge'].value_counts(normalize=True).

Checklist operativo

  • Claves limpias (tipos y padding), sin NaNs.
  • Subset de columnas de right (reduce memoria y colisiones de nombres).
  • Post-merge: asserts de unicidad si se esperaba 1:1.

Complementa operacion/logging_etl.md y los contratos de claves en /referencia/nucleo/dbml_fuente_de_verdad.