Check diario de frescura de raw.*
Reemplaza a DVT (deprecado el mismo día): un check mucho más
chico a propósito — un solo script Python, sin contenedor propio, que compara
solo el número de filas modificadas en los últimos 30 días entre cada
tabla de raw.* en Postgres y su fuente real en .207 (ver
Conexiones a TRIVASADB). No valida columnas ni
schema — ese alcance era justo lo que hacía pesado a DVT (imagen Docker
propia, mapping de columnas, dos herramientas de comparación distintas). Este
check cubre la pregunta que de verdad importa día a día: ¿la carga de esta
mañana trajo lo que debía traer, o algo se quedó atrás?
Por qué 30 días y fecha_ult_modif
Las 15 tablas de raw.* comparten una columna de auditoría —
fecha_ult_modif en Postgres, Fecha_Ult_Modif en .207 — que es la misma
que ya usan los pipelines de dlt como cursor incremental.
Reusarla para el check evita inventar un criterio nuevo: si dlt confía en esa
columna para saber qué sincronizar, el check confía en ella para saber qué
comparar. Filtrar a los últimos 30 días evita escanear el histórico completo
en tablas grandes (movimiento tiene 4.5M+ filas totales) para un chequeo que
solo necesita confirmar que lo reciente está al día.
Tolerancia: por qué no es una comparación exacta
.207 es la base operativa en vivo — sigue recibiendo escrituras entre que
corre el último sync de dlt (6:45 AM) y el momento en que corre este check
(7:00 AM). Una diferencia de un puñado de filas ahí es lag normal, no una
falla real (mismo criterio que ya usaba DVT con su --threshold, y que
documenta Warehouse Postgres § verificación).
Umbral: max(5, 0.1% del conteo en la fuente) — por debajo, warn; por
encima, fail.
Corrida fuera de horario, diffs grandes son esperados: una prueba manual
corrida a mitad del día (varias horas después del sync de las 6:45 AM, con
producción activa todo ese tiempo) va a mostrar diffs de cientos o miles de
filas en tablas de alto volumen como movimiento — no es un bug del check,
es exactamente lo que debe detectar. La corrida real de cron ocurre 15
minutos después de la última carga, cuando el hueco esperado es mínimo.
Cron
0 7 * * * cd ~/trivasa-bi-dev/raw-checks && venv/bin/python3 check_raw_freshness.py
7:00 AM UTC (1:00 AM hora local Mexico) — mismo horario que usaba DVT, 15
minutos después de que termina el último de los 4 crons de
pipelines dlt (6:45 AM, movimiento).
Dashboard en Perses
https://data.frento.com.mx, proyecto soda, dashboard “Soda Data Quality
(real)” (job="soda_real") — existía diseñado desde un intento anterior con
Soda Core (ver “Por qué se reemplazó Soda Core” en DVT) pero
nunca llegó a desplegarse; se revivió y se le agregaron 2 paneles nuevos para
esta ocasión:
- Los 3 stats + barras apiladas que ya traía (fails/warnings totales, health score, checks por outcome y día).
- Fallos/warnings por tabla — qué tabla específica de
raw.*está desfasada, sin saturar la vista con las que están enpass. - Diferencia de filas por tabla — el valor numérico real (fuente −
destino) en el tiempo, vía
unwrapde LogQL sobre el campodiffdel JSON posteado a Loki, no solo el veredicto pass/warn/fail.
Los otros dos dashboards del mismo proyecto Perses (dvt-data-quality,
data-health-status, job="dvt") quedan sin datos nuevos desde que DVT se
decomisionó — no se borraron ni se re-apuntaron, simplemente van a mostrar
“sin datos” indefinidamente a menos que algo vuelva a postear con ese job.
Sin notificación activa — decisión deliberada
El script no manda alertas a ningún canal externo (Telegram, email) si sale
en fail — evaluado y descartado el 2026-08-10: no justificaba montar un bot
o webhook dedicado solo para esto. En su lugar, dos cosas baratas para que
revisar el estado de hoy no implique leer el log completo:
- Banner al final del output (
✅ PASS/⚠️ WARN/❌ FAIL+ conteo), lo último que se ve contaildel log de cron. last_status.txt(mismo directorio que el script) — se sobreescribe en cada corrida con el resultado y el detalle de cualquier tabla que no esté enpass.cat ~/trivasa-bi-dev/raw-checks/last_status.txtes la forma rápida de saber si hoy hubo problema, sin abrir Perses ni el log.
El dashboard de Perses sigue siendo la fuente de verdad para tendencia en el tiempo; esto es solo para el chequeo del día a día.
Retención en MinIO (relacionado, no de este check)
El bucket lightdash de MinIO (donde caen las capturas del
carrusel de dashboards) no tenía ninguna regla
de expiración — crecía sin límite con cada render horario de los 3
schedulers. Se agregó una regla de ciclo de vida el mismo día:
docker exec lightdash-minio mc ilm add --expire-days 7 local/lightdashObjetos de más de 7 días se borran solos (MinIO lo evalúa en un scan
periódico, no al instante). No relacionado al check de frescura de raw.*
más allá de haberse revisado en la misma sesión de mantenimiento.
Véase también
- DVT — reconciliación real fuente/destino — el check anterior, más completo (columnas + schema) pero deprecado por peso.
- Pipelines dlt — los 4 crons que sincronizan lo que este check valida, mismo horario de referencia.
- Conexiones a TRIVASADB — por qué
.207y no.200/.204. - Warehouse Postgres —
raw.*, el destino que se valida. sources/trivasa/raw-freshness-checks/cierre.md— cierre técnico: script completo, YAML del dashboard, queries LogQL exactas.