Validación y Calidad de Datos
Las comprobaciones de esquemas y estadísticas en los límites de la canalización detectan ingestas incorrectas antes de que contaminen los marts: Pandera para DataFrames de Python, Great Expectations para contratos de datos documentados.
Receta
Tarjeta de receta de referencia rápida, lista para copiar y pegar.
import pandera.pandas as pa
schema = pa.DataFrameSchema({
"order_id": pa.Column(int, unique=True, nullable=False),
"revenue": pa.Column(float, pa.Check.ge(0)),
"region": pa.Column(str, pa.Check.isin(["East", "West", "Central"])),
})
def validate_orders(df):
return schema.validate(df, lazy=True)Cuándo usar esto:
- Cada etapa de ETL antes de las escrituras de sobrescritura
- Pruebas de CI en muestras fijas de Parquet
- Paneles de SLA sobre frescura y volumen
- Datos regulatorios o financieros que requieren un rastro de auditoría
Ejemplo de Trabajo
import pandas as pd
import pandera.pandas as pa
from pandera import Check, Column, DataFrameSchema
orders_schema = DataFrameSchema(
{
"order_id": Column(int, unique=True, nullable=False),
"revenue": Column(float, checks=Check.ge(0)),
"region": Column(str, checks=Check.isin(["East", "West", "Central"])),
"ordered_at": Column("datetime64[ns, UTC]", nullable=False),
},
strict=False,
coerce=True,
)
def load_orders(path: str) -> pd.DataFrame:
df = pd.read_parquet(path)
try:
return orders_schema.validate(df, lazy=True)
except pa.errors.SchemaErrors as err:
# Poner en cuarentena las filas incorrectas para su inspección
failure_cases = err.failure_cases
failure_cases.to_csv("quarantine/schema_failures.csv", index=False)
raise
# Comprobación estilo Great Expectations (API conceptual de GE)
def gx_style_checks(df: pd.DataFrame) -> None:
assert len(df) > 0, "lote vacío"
assert df["order_id"].is_unique.all()
assert df["revenue"].between(0, 1_000_000).mean() > 0.99Lo que esto demuestra:
- Esquema Pandera con गोष्ट (coerción) y reporte de múltiples errores en modo diferido (lazy)
- Artefacto de cuarentena en caso de fallo
- Asertos ligeros que complementan esquemas formales
- Tipado de columna datetime UTC
Inmersión Profunda
Cómo Funciona
- Pandera valida la forma del DataFrame, los dtypes y las comprobaciones personalizadas en Python.
- Great Expectations almacena Expectation Suites, valida lotes, genera Data Docs.
- Fallar cerrado: la tarea del orquestador no debe promocionar el mart en caso de error de validación.
- Combinar esquema (estructura) con comprobaciones de anomalías (volumen, tasa de nulos).
Tipos de Comprobación
| Tipo | Ejemplo |
|---|---|
| Estructural | columna existente, dtype, único |
| Rango | ingresos >= 0 |
| Pertenencia a conjunto | región en lista permitida |
| Estadístico | recuento de filas dentro de 3 sigmas de la mediana de 7 días |
Notas de Python
# Polars con pandera.polars
import polars as pl
import pandera.polars as pa
schema = pa.DataFrameSchema({"id": pa.Column(int)})
schema.validate(pl.DataFrame({"id": [1, 2]}))Trampas Comunes
- Validar solo en notebook - la producción omite las comprobaciones. Solución: llamar al validador en
@taskantes de escribir. lazy=Falseen esquemas amplios - se detiene en el primer error. Solución:lazy=Truepara un informe completo de fallos.- Recuentos de filas exactos frágiles - inestables con tráfico real. Solución: comprobaciones de rango frente al promedio móvil.
- Fallos solo de advertencia - los datos incorrectos aún se envían. Solución: lanzar y bloquear sensores descendentes.
- Deriva del esquema sin versión - el despliegue falla silenciosamente. Solución: etiquetar versiones del esquema con git junto con el código de la canalización.
Alternativas
| Alternativa | Usar Cuando | No Usar Cuando |
|---|---|---|
| Pruebas de dbt | Transformaciones nativas del almacén de datos | Limpieza previa de pandas |
| Soda Core | Comprobaciones YAML en varios almacenes de datos | Ya se usa GE de forma estandarizada |
| Modelos Pydantic | Eventos de API JSON antes del DataFrame | Cargas masivas de archivos columnares |
| Aserto manual | Scripts pequeños | Cualquier canalización de producción compartida |
Preguntas Frecuentes
¿Pandera o Great Expectations?
- Pandera: integración estrecha con pandas/Polars y pytest.
- GE: portal de documentación e historial de lotes para equipos de operaciones.
¿Dónde validar?
- Después de la extracción y después de la transformación, antes de la promoción del mart.
- En el límite de la API para eventos de streaming.
¿Cómo pruebo los validadores?
import pytest
import pandera.errors
def test_rejects_negative_revenue(bad_df):
with pytest.raises(pandera.errors.SchemaError):
orders_schema.validate(bad_df)¿Pueden las comprobaciones ser asíncronas con el almacén de datos?
- GE realiza puntos de control contra tablas de Snowflake/BQ después de la carga.
- Pandera en muestras extraídas a pandas para lógica personalizada intensiva.
¿Cómo manejo advertencias vs errores?
- Los errores bloquean la canalización; las advertencias abren tickets.
- No mezclar sin un runbook claro para el personal de guardia.
¿Picos en la tasa de nulos?
- Comparar con la distribución de los últimos 14 días.
- Alertar cuando se envía una nueva versión de la fuente.
¿Duplicados de clave primaria?
- Fallo duro: los duplicados rompen las fusiones y los totales de ingresos.
- Poner en cuarentena todo el lote si hay más de 0 duplicados.
¿Evolución del esquema?
- Añadir columnas opcionales con valores predeterminados primero.
- Los cambios que rompen requieren una tabla de mart versionada o un plan de relleno.
¿PII en registros de fallos?
- Registrar nombres de columnas y nombres de reglas, no cargas útiles de filas.
- Acceso controlado a los archivos en cuarentena.
¿Integrar con Airflow/Prefect?
- Tarea de validación dedicada que controla las tareas posteriores a través de la dependencia de tareas.
Relacionado
- Limpieza y Transformación de Datos - correcciones antes de validar
- dbt con Python - pruebas en el almacén de datos
- Mejores Prácticas de Ingeniería de Datos - puertas de calidad
- Fiabilidad del Flujo de Trabajo - fallar vs reintentar
Versiones de la Pila: Esta página fue escrita para Python 3.14.0 (estable 3.14, mantenimiento 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, y uv 0.6+.