Sincronizar datos entre sistemas sin duplicados ni descuadres depende de dos decisiones de diseño: que cada carga pueda repetirse sin efectos secundarios y que una reconciliación diaria compruebe que origen y destino suman lo mismo. Leer solo los cambios, por marca de tiempo o por CDC, reduce el coste de cada ejecución. Lo resolvemos dentro de nuestros proyectos de integración de sistemas y software a medida.
Un fallo de sincronización rara vez se ve el día que ocurre. Un pedido duplicado infla la facturación del mes y el descuadre aparece en el cierre, cuando alguien tiene que revisar a mano qué registro sobra. Si ese proceso alimenta un data warehouse para pymes en Madrid, el error se reparte a todos sus informes.
Al terminar sabrás qué método de detección de cambios usar y cómo demostrar cada mañana que no falta ni sobra nada, apoyándote en la elección entre API, webhook o cola de mensajes para el transporte.
Qué es sincronizar datos entre sistemas
Sincronizar datos entre sistemas es mantener copias coherentes de una misma entidad, como un cliente o un pedido, en programas distintos que no comparten base de datos. Un proceso ETL extrae los cambios del origen y los carga, adaptados al modelo del destino, con un identificador común que impide crear duplicados.
Con sistemas sin API, la sincronización pasa por un middleware a medida entre ERP, CRM y legacy que traduce formatos y centraliza las reglas.
Carga completa, incremental o CDC: cómo detectar cambios
Una ETL detecta los cambios del origen de cuatro formas habituales, y cada una tiene un punto ciego distinto:
- Carga completa: copia toda la tabla en cada ejecución. Sí: tablas maestras pequeñas. No: tablas de millones de filas.
- Incremental por marca de tiempo: lee las filas modificadas después de la última carga. Sí: el origen actualiza esa columna en cada cambio. No: el origen borra filas físicamente, porque un borrado no deja fecha.
- Incremental por identificador creciente: lee los identificadores mayores que el último cargado. Sí: tablas donde solo se inserta, como apuntes contables. No: registros que se editan después.
- CDC (captura de cambios de datos): lee el registro de transacciones del origen, borrados incluidos. En PostgreSQL se apoya en la decodificación lógica.
Con marca de tiempo, solapa unos minutos la ventana de lectura: una transacción larga puede confirmar filas con una fecha anterior a tu última marca. Con CDC, la documentación de decodificación lógica de PostgreSQL advierte que tras una caída un slot de replicación puede reenviar cambios ya entregados, y que un slot que nadie consume impide borrar el WAL que necesita y sigue ocupando disco. Lo primero obliga a cargar de forma idempotente; lo segundo, a vigilar el slot.
Idempotencia: repetir una carga sin duplicar datos
Una carga es idempotente cuando ejecutarla dos veces deja el destino igual que ejecutarla una. En PostgreSQL se construye con INSERT ... ON CONFLICT DO UPDATE, que según la referencia de INSERT en PostgreSQL garantiza un resultado atómico de inserción o actualización incluso con alta concurrencia.
- Identificador de origen único: guarda el id del sistema origen con un índice único y nunca cruces registros por nombre o por email.
- Actualiza solo si es más nuevo: compara la fecha de modificación para que un cambio antiguo reenviado no pise uno reciente.
- Borrado lógico: marca el registro como eliminado en vez de borrarlo, para que la reconciliación pueda contarlo.
- Reintentos con el mismo identificador de envío: si el transporte es una API, cada reenvío repite ese identificador y el receptor descarta el repetido.
Es el principio que aplica un ERP multiempresa que no duplica datos y el que evita silos en la integración de sistemas en Madrid con una fuente de verdad por dato.
Reconciliación: demostrar que origen y destino cuadran
La reconciliación compara cada día el número de registros y la suma de importes por fecha en origen y destino, y señala solo los días que difieren.
Contar filas no basta: un duplicado y una pérdida el mismo día dan el mismo total. Por eso se compara también una huella del contenido diario, y si difiere se revisa solo ese día. La misma técnica valida la carga inicial de un plan de migración de datos con reconciliación por lotes y es la que da credibilidad a cualquier cifra, se pinte en Power BI o en un panel propio.
CodeZone Pro Tip: compara por día los totales de origen y destino junto con una huella del contenido, y devuelve solo los días que no cuadran.
import hashlib
from collections import defaultdict
from decimal import Decimal
def resumen_por_dia(filas):
"""filas: iterable de (id_origen, fecha_iso, importe). Devuelve {fecha: (n, total, huella)}."""
grupos = defaultdict(list)
for id_origen, fecha, importe in filas:
# Decimal y no float: un redondeo binario no debe disparar un falso descuadre
grupos[fecha].append((str(id_origen), Decimal(str(importe)).quantize(Decimal("0.01"))))
resumen = {}
for fecha, regs in grupos.items():
regs.sort() # cada sistema devuelve las filas en otro orden; la huella no debe cambiar
huella = hashlib.sha256("|".join(f"{i}:{imp}" for i, imp in regs).encode()).hexdigest()
resumen[fecha] = (len(regs), sum(imp for _, imp in regs), huella)
return resumen
def descuadres(origen, destino):
"""Días que difieren. La huella detecta un duplicado y una pérdida que se compensan en total."""
a, b = resumen_por_dia(origen), resumen_por_dia(destino)
vacio = (0, Decimal("0.00"), None)
return {d: (a.get(d, vacio), b.get(d, vacio)) for d in sorted(a.keys() | b.keys())
if a.get(d, vacio) != b.get(d, vacio)}
if __name__ == "__main__":
# Ejemplo hipotético: el 19 llega P2 duplicado como P2b y se pierde P4; el 20 se pierde P3
erp = [("P1", "2026-10-19", "120.50"), ("P2", "2026-10-19", "80.00"),
("P4", "2026-10-19", "80.00"), ("P3", "2026-10-20", "45.10")]
almacen = [("P1", "2026-10-19", "120.50"), ("P2", "2026-10-19", "80.00"),
("P2b", "2026-10-19", "80.00")]
for dia, (o, d) in descuadres(erp, almacen).items():
print(dia, "origen:", o[:2], "destino:", d[:2], "huella igual:", o[2] == d[2])En el ejemplo, el día 19 cuadra en pedidos e importe y la huella lo marca igualmente. Ese informe matinal sustituye la revisión manual del cierre: sabes qué día falla y en qué sistema sobra o falta el registro antes de que la cifra llegue a facturación.
Lo Que Cuesta Cuadrar a Mano Cada Cierre de Mes
Una sincronización sin idempotencia ni reconciliación funciona hasta el primer reintento, y desde entonces cada informe arrastra la duda. Diseñar ambas desde el principio cuesta poco más que el conector y evita que administración acabe haciendo de control de calidad de la integración.
En Codezone diseñamos sincronizaciones entre tu ERP y el resto de programas que se pueden repetir sin duplicar. Cuéntanos qué sistemas no te cuadran y revisamos dónde se pierden los datos.