
Modernizar una base de datos legacy sin reescribirla
La tentación del big-bang rewrite es comprensible: un esquema heredado con nombres crípticos, tipos inconsistentes y reglas de negocio embebidas en triggers invita a empezar de cero. Pero reescribir implica congelar el negocio, subestimar la lógica oculta y arriesgar años de trabajo sin entrega intermedia. La alternativa que defiendo es evolución incremental: el sistema legacy sigue operativo mientras una capa de abstracción expone un contrato limpio hacia fuera.
El legacy no desaparece de la noche a la mañana
Una base Access de décadas, un Azure SQL con stored procedures acumulados o un PostgreSQL con convenciones propias comparten un patrón: funcionan lo suficiente como para no apagarlas. Apagarlas exige reemplazar no solo tablas, sino procesos, informes y conocimiento tácito.
La modernización comienza reconociendo ese hecho. El diagrama de este artículo muestra un lado oscuro —servidores, cables, documentación amarillenta— conectado por un puente de descubrimiento, comprensión, abstracción, adaptación y evolución hacia un dominio legible.
Vistas limpias cuando aportan valor
Las vistas SQL pueden traducir nombres crípticos a vocabulario de dominio sin mover datos. No son gratis: hay que documentar su procedencia y vigilar el rendimiento. Cuando aportan valor —lecturas frecuentes, contratos estables— simplifican el paso siguiente.
Cuando no aportan valor —lógica demasiado enrevesada en SQL— conviene subir la abstracción a código.
Anti-corruption layer
Mapping explícito entre filas legacy y modelos Pydantic (o equivalentes) concentra las rarezas en un módulo acotado. El dominio habla de Customer, Order, Payment; el mapping sabe que tbl_cust_01 usa códigos de tres letras y fechas como enteros.
Esa capa es la frontera donde termina el caos heredado y empieza el contrato nuevo. Todo lo demás —API, frontend, tests— consume el modelo limpio.
API como contrato hacia fuera
FastAPI (o el framework elegido) expone endpoints que no filtran anomalías de almacenamiento. El frontend no hereda columnas calculadas en triggers ni claves compuestas opacas.
La API también delimita qué operaciones son posibles: lecturas amplias, mutaciones acotadas, operaciones prohibidas hasta completar migración parcial.
Sustitución progresiva
Con el tiempo, tablas nuevas pueden absorber funcionalidad mientras el legacy se reduce a un subconjunto de lecturas o a un sink de sincronización. Cada paso debe ser reversible o al menos observable: métricas de divergencia, tests de equivalencia, smoke de regresión.
Este enfoque se complementa con Transactional Outbox cuando hay que notificar cambios a otros sistemas sin dual-write, y con convivencia PostgreSQL/Azure SQL cuando el destino es otro motor relacional.
Límites
La abstracción no elimina deuda: la localiza. Alguien debe mantener el mapping cuando el legacy cambia. Tampoco sustituye análisis de rendimiento ni gobernanza de datos sensibles.
Pero evita la apuesta binaria entre «seguir como está» y «reescribir todo». En sistemas reales, la vía viable suele ser la del puente.