Volver al portfolio
ENESFRPT
Datos

Cómo migré un negocio en producción de Google Sheets a PostgreSQL

12 min de lectura · 2026

Después de que una inundación catastrófica destruyera nuestro almacén y nos obligara a reconstruir desde cero, decidí hacerlo bien esta vez: migrar de las hojas de cálculo a una base de datos de verdad, construir un ERP en condiciones y no volver a perder nunca el control de nuestros datos. Esta es la historia de esa migración.

Contexto: la inundación que lo cambió todo

En abril de 2024 nos mudamos a una nave industrial en Alfafar, Valencia, para escalar las operaciones. Seis meses después, en octubre de 2024, la DANA —un fenómeno meteorológico catastrófico— azotó Valencia. Nuestro almacén estaba en una de las zonas más afectadas. El agua de la riada destruyó el inventario, los equipos y meses de impulso operativo.

Lo que vino después fueron dos meses de gestión de crisis que no tenían nada que ver con el código. En las semanas posteriores a la inundación, voluntarios y militares vinieron a ayudarnos a recuperar las operaciones del almacén: inventario, equipos, limpieza y logística. Luego llegaron los partes a los seguros, los presupuestos de emergencia sin ingresos y el reseteo mental de ver todo lo que habías construido bajo el agua. Fue el periodo más duro de mi vida.

Pero también fue un reseteo. Cuando reconstruimos —y lo hicimos— tomé una decisión: esta vez lo haríamos bien. Se acabó el apaño. Se acabó el "ya está bien así". Reconstruimos el equipo de 2 a 5 empleados, y me comprometí a construir una infraestructura en condiciones: una base de datos de verdad, un ERP de verdad, documentación de verdad. La era de Google Sheets había terminado.

El punto de partida: por qué Google Sheets tenía que desaparecer

Cuando fundé la empresa, Google Sheets era la elección obvia para gestionar el inventario. Es colaborativa, visual, todo el mundo sabe usarla y es gratis. Mi equipo de almacén podía actualizar las ubicaciones del stock. Yo podía escribir fórmulas. Todos podían verlo todo en tiempo real.

El problema es que Google Sheets nunca se diseñó para ser una base de datos. Y cuando procesas miles de SKU de liquidación de Amazon repartidos entre varias cuentas de marketplace, empieza a romperse de formas difíciles de predecir:

Tenía que migrar. Pero no podía parar el negocio para hacerlo.

La restricción que lo cambió todo

Esto no era una migración de proyecto paralelo de fin de semana. Era un negocio en producción con restricciones reales:

No podía darle a un interruptor. Necesitaba una estrategia de migración que me permitiera avanzar de forma incremental, validar en cada paso y dar marcha atrás si algo salía mal.

El pipeline de 5 fases

Diseñé la migración como un pipeline de 5 fases, donde cada fase podía ejecutarse de forma independiente en modo dry-run o execute:

Phase 1: EXTRACT & ANALYZE
  └─ Pull all data from 3 Google Sheets tabs → CSVs
  └─ Generate analysis report (row counts, data types, anomalies)

Phase 2: VALIDATE
  └─ Parse every row against the target PostgreSQL schema
  └─ Type conversions (dates, decimals, booleans, enums)
  └─ Flag invalid rows with specific error reasons
  └─ Generate validation report

Phase 3: MIGRATE
  └─ Load validated data into PostgreSQL
  └─ Respect foreign key ordering (items → listings → sales)
  └─ Dry-run mode: simulate without writing
  └─ Execute mode: actual INSERT with transaction safety

Phase 4: SYNC OPERATIONAL DATA
  └─ Pull "Prep de Pedidos" (order preparation) tab
  └─ Match warehouse status to database records
  └─ Update pick/pack states

Phase 5: CONTINUOUS SYNC
  └─ Daily: Sheet → DB delta sync
  └─ Handles new rows, updates, and edge cases
  └─ Runs alongside the database as source of truth transitions

Las partes difíciles de las que nadie habla

1. La calidad de los datos nunca es la que crees

Google Sheets es "flexible", lo que significa que tus datos son un desastre. Esto es lo que encontré cuando intenté parsear más de 8.000 filas de inventario:

Dediqué más tiempo a escribir código de limpieza y normalización de datos que a la propia lógica de migración. Cada caso límite que arreglaba revelaba otros dos.

2. Conciliación financiera por camión

Compramos liquidaciones de Amazon por camiones completos. Cada camión tiene un código (A2Z33838, A2Z34102, etc.) y un coste. A efectos fiscales, necesito saber: por cada camión, cuánto pagamos, cuánto vendimos, qué queda en stock y cuál es el margen.

En Google Sheets, esto era una pestaña con fórmulas SUMIFS. En PostgreSQL, necesitaba reconstruirlo como una vista (v_resumen_a2z) y validar que las cifras cuadraban al céntimo.

Truckload  | Sheet Total | DB Total  | Diff    | Status
A2Z33838   | €14,230.50  | €14,230.50| €0.00   | ✓ MATCH
A2Z34102   | €8,445.00   | €8,445.00 | €0.00   | ✓ MATCH
A2Z34567   | €11,200.75  | €11,198.25| €2.50   | ✗ INVESTIGATE
           |             |           |         |   → 1 sale missing
           |             |           |         |   → LPN XU-20240312

Generé cientos de estos informes de conciliación. Cada discrepancia había que investigarla. La mayoría se debían a problemas de sincronización (una venta registrada en la hoja pero aún no extraída de la API de Wallapop) o a que mis empleados hacían correcciones manuales directamente en la hoja.

3. El periodo de operación en paralelo

Durante unas 3 semanas, ejecuté ambos sistemas a la vez. Google Sheets seguía siendo la fuente de verdad para mis empleados, mientras la base de datos se iba poblando y validando en segundo plano.

Cada mañana:

  1. Ejecutar el script de sincronización para traer los cambios de Sheets a PostgreSQL
  2. Revisar el informe de conciliación en busca de discrepancias
  3. Investigar y arreglar cualquier incidencia (normalmente de 2 a 5 al día)
  4. Probar los dashboards de Retool contra datos reales
  5. Procesar los pedidos del día (las operaciones reales del negocio)

Cada tarde:

  1. Revisar qué habían cambiado los empleados en Sheets durante el día
  2. Ejecutar la sincronización de nuevo
  3. Verificar que los totales financieros seguían cuadrando

Era agotador. Básicamente estaba operando dos sistemas, haciendo mi trabajo como gestor del negocio Y depurando casos límite de la migración. Pero era la única forma de tener confianza antes del corte definitivo.

4. Los scripts de corrección

Ninguna migración es limpia. Escribí más de 15 scripts de corrección especializados para incidencias descubiertas durante o después del periodo en paralelo:

Cada script de corrección seguía el mismo patrón: diagnosticar → dry-run → revisar → ejecutar → verificar. Sin arreglos a ciegas.

5. Explicárselo al equipo

La parte más difícil no fue técnica. Fue explicarles a 4 empleados sin perfil técnico por qué estábamos cambiando su forma de trabajar.

"La hoja de cálculo funciona bien" es algo perfectamente razonable que diga un operario de almacén. Y desde su punto de vista, sí que funcionaba bien. Ellos no veían los límites de la API, los riesgos de corrupción de datos ni los scripts cayéndose a las 3 de la mañana por un recálculo de fórmulas.

Tuve que:

El corte definitivo

Tras 3 semanas de operación en paralelo, más de 200 informes de conciliación y 15 scripts de corrección, documenté el plan del corte definitivo:

CUTOVER CHECKLIST
─────────────────
[✓] All truckloads reconciled to €0.00 difference
[✓] All active listings matched between Sheet and DB
[✓] All pending orders present in both systems
[✓] Retool modules tested: orders, items, sales, invoicing
[✓] Employees trained on new workflow
[✓] Sheet set to read-only with banner: "USE RETOOL"
[✓] Automated extractors pointed to DB (not Sheet)
[✓] Backup snapshot of all table counts taken
[✓] Rollback procedure documented (Sheet restore)

El corte en sí fue anticlimático, que es exactamente lo que quieres. Cambié los extractores para que escribieran directamente en PostgreSQL, puse Google Sheets en solo lectura y le dije a mi equipo: "a partir de hoy, usad Retool para todo".

Lo que construí (el stack técnico)

La migración no eran solo scripts. Requería construir toda la infraestructura de destino:

Resultados

6 meses después de la migración:

Qué haría diferente

Si volviera a hacerlo:

  1. Empezar con la base de datos desde el primer día. El impuesto del "ya migraremos más adelante" es real y caro. Incluso un montaje sencillo de PostgreSQL + un frontend de ERP a medida en Retool desde el principio me habría ahorrado cientos de horas
  2. Automatizar las comprobaciones de conciliación en lugar de ejecutarlas a mano cada mañana. Un pipeline tipo CI que me envíe un email solo cuando se detecten discrepancias
  3. Construir primero la interfaz de Retool y migrar después. Las construí en paralelo, lo que significó que los empleados vieron interfaces a medio terminar durante el periodo de transición. Si la interfaz hubiera estado pulida antes del corte, la adopción habría sido más fluida

La conclusión

Migrar un sistema en producción no es un problema técnico. Es un problema operativo que requiere soluciones técnicas. El código es quizá el 30 % del trabajo. El otro 70 % es:

Hice todo esto como ingeniero en solitario llevando un negocio con 5 empleados. Sin un equipo de DBA. Sin QA dedicado. Solo ingeniería sistemática y mucho café.

El pipeline de migración es de código abierto: github.com/AspiranteD/sheets-to-postgres-migration