🎯 Situación
Una analista de datos en un cliente de logística construyó un sólido script Python en tres semanas: extraía datos diarios de envíos de una API, los limpiaba con pandas y los cargaba en Azure SQL. El script funcionaba perfectamente. Lo ejecutaba manualmente cada mañana a las 7 AM desde su laptop. Cuando estaba de vacaciones, los datos dejaban de fluir. Cuando su laptop estaba en reparación, el dashboard de Power BI mostraba una semana de espacios en blanco. El script era bueno. El despliegue no lo era.
⚠️ El reto
📋 Opciones 1 y 2: programación local
- Programador de tareas de Windows — clic derecho en tu script → Crear tarea → Disparadores → diariamente a las 7 AM. Funciona mientras la máquina esté encendida. Costo cero.
- cron de macOS/Linux — agregar: 0 7 * * * /usr/bin/python3 /ruta/al/script.py a crontab. Misma limitación: requiere que la máquina esté corriendo.
- Adecuado para: scripts personales, máquinas de desarrollo, datos de baja importancia que toleran ejecuciones perdidas ocasionales.
- No adecuado para: pipelines de producción donde Power BI depende de que los datos estén actualizados cada mañana.
⛅ Opciones 3 y 4: programación en la nube — nivel producción
- Azure Functions (plan de Consumo) — desplegar tu script Python como una Function, configurar un disparador Timer (sintaxis cron), se ejecuta en la nube según el horario independientemente de cualquier laptop. Costo: ~$0.20/mes para ejecuciones diarias.
- Azure Data Factory (ADF) — orquestación de pipelines con una actividad Python. Más complejo de configurar, pero incluye gestión de dependencias, lógica de reintentos y monitoreo integrado. Adecuado para pipelines de múltiples pasos.
- GitHub Actions — gratuito para repos públicos, $0/mes para 2,000 minutos/mes en privados. Programar un workflow para clonar tu repo y ejecutar el script. Los logs son automáticos. Buen punto medio entre local y Azure completo.
🔍 Análisis
Los tres requisitos de producción para cualquier script programado:
- Logging — escribir la salida de cada ejecución en un archivo o base de datos: hora de inicio, hora de fin, filas procesadas, errores. Si algo se rompe, necesitas saber qué pasó y cuándo.
- Alerta de errores — si el script falla, un correo o notificación de Teams se envía inmediatamente. No a la mañana siguiente cuando alguien nota que el dashboard está en blanco.
- Idempotencia — si el script se ejecuta dos veces (ej. un reintento después de una falla), debe producir el resultado correcto, no insertar datos dos veces. Usar UPSERT (INSERT ... ON CONFLICT UPDATE) o patrones de truncar-y-recargar.
✓️ Buena práctica
El wrapper de producción mínimo para cualquier script Python de pipeline:
import logging, sys
from datetime import datetime
logging.basicConfig(
filename='pipeline.log',
level=logging.INFO,
format='%(asctime)s %(levelname)s %(message)s'
)
def run_pipeline():
logging.info("Pipeline started")
try:
# --- your pipeline code here ---
rows = extract_from_api()
cleaned = transform(rows)
load_to_sql(cleaned)
logging.info(f"Success: {len(cleaned)} rows loaded")
except Exception as e:
logging.error(f"Pipeline failed: {e}")
send_alert(str(e)) # Teams / email notification
sys.exit(1)
if __name__ == "__main__":
run_pipeline()
💡 Síntesis
La programación es el último 10% de construir un pipeline — y la parte que determina si realmente funciona en producción. Un script ejecutado manualmente es una dependencia: depende de una persona, una laptop y una rutina. Un script programado, con logs y alertas es infraestructura.
👉 El script está terminado cuando se ejecuta solo.
Logging, alertas, programación — ese es el 20% que hace confiable el 80%.