Esta página describe Calíope 1.8, la versión que estoy construyendo ahora mismo. La 1.7 está en la App Store para Mac, iPad, iPhone, Apple Watch, Apple TV y Apple Vision Pro. El changelog dice en qué versión llegó cada función.

Añade un botón «Abrir en Calíope» a cada tema. Sólo funciona con la app instalada.

Migración de datos

Migrar objetos entre servidores

Copia tablas, vistas, rutinas, triggers y eventos a otro servidor, o a otra base del mismo.

Dónde está: Espacio de Trabajo › Herramientas › Migración de datos

Abre Migración de datos desde la barra lateral del workspace. Copia tablas, vistas, rutinas, triggers y eventos de esta conexión a otro servidor, o a otra base del mismo.

Elige qué copiar en el árbol de la izquierda. Su cabecera tiene un filtro por nombre: escribe parte del nombre de una base o de un objeto para acotar la lista sin desplegar base por base. Los objetos se agrupan por tipo (Tablas, Vistas, Rutinas, Triggers y Eventos); pulsar un objeto lo marca, y la casilla de cada base marca o desmarca todo su contenido, con la cuenta de marcados sobre el total al lado. Limpiar vacía la selección. El orden lo fija Calíope —tablas, vistas, rutinas, triggers y eventos— para que cada objeto encuentre creado aquello de lo que depende.

Elige adónde va. Junto a Destino:, abre Seleccionar servidor destino, elige una de las conexiones guardadas en el Gestor de conexiones y pulsa Conectar. En En la base, escribe la base en la que acabarán los objetos; vacía, cada objeto conserva la base que tiene en el origen. Calíope crea esa base si no existe, y reescribe las referencias de una vista para que lea de ella.

Opciones: Reemplazar en destino borra todo lo marcado antes de crear nada —primero lo que depende de las tablas, y las tablas hijas antes que sus madres—, así que repetir la misma migración es seguro; Exportar datos copia las filas de cada tabla; Omitir FK checks apaga la comprobación de claves foráneas mientras se carga cada objeto, para que las tablas puedan llegar en cualquier orden.

Pulsa Migrar. El registro da una línea por objeto, con la base a la que fue y, en una tabla, las filas copiadas. Detener para entre un objeto y el siguiente.

Las claves foráneas de las tablas copiadas se crean al final, cuando ya están todas con sus filas: el orden en que llegan deja de importar.

Entre familias de motor distintas un aviso junto a Migrar lo dice antes de ejecutar nada: el DDL de un motor no lo entiende el otro, así que no se crea nada. Sólo se copian filas, a tablas del mismo nombre que ya existan en el destino, emparejando las columnas por nombre; una tabla que el destino no tiene, o un objeto que no es tabla, se salta y el registro lo dice.

Dentro de una misma familia el DDL viaja tal cual, pero un producto puede no tener lo que tiene otro. Antes de crear nada, el registro dice qué objetos marcados no puede tener el destino —un trigger, una rutina o un evento que no tiene, una tabla con un tipo de columna que le falta— y los salta, también de Reemplazar en destino; y qué tablas llegan sin un tipo de índice que el destino no construye.

TiDB

Desde MySQL o MariaDB no viajan los triggers, las rutinas ni los eventos, que TiDB no tiene, ni una tabla con una columna espacial (POINT, GEOMETRY…); un índice FULLTEXT no se crea. Una columna AUTO_RANDOM conserva sus valores: Calíope enciende allow_auto_random_explicit_insert en la sesión del destino mientras copia.

SQL Server

Una columna IDENTITY conserva sus valores (Calíope enciende IDENTITY_INSERT mientras copia), pero no su contador: en el destino la fila siguiente sigue desde el máximo copiado. Cada objeto cae en su esquema, que se crea si no existe. Con sólo el nombre de una base en En la base, cada objeto conserva su esquema: demo.dbo va a copia.dbo, y demo.rrhh a copia.rrhh.

PostgreSQL

Aquí una base es un esquema de la base conectada: En la base nombra el esquema al que van los objetos, y se crea si no existe. Los tipos que usan las tablas copiadas —un ENUM, un dominio— se crean antes; uno que ya existe en el destino se conserva tal cual, porque rehacerlo obligaría a soltar cada columna que lo usa. El search_path de una función copiada apunta al esquema de destino, así que sus triggers escriben allí y no en el origen.

ClickHouse

Cada tabla se crea con el DDL que guarda el servidor —motor, PARTITION BY, ORDER BY, TTL y SETTINGS incluidos—, y no hay claves foráneas ni Omitir FK checks. Las filas van en INSERT de cien en cien, y una columna Array, Map o Tuple llega con su tipo. Una vista materializada se crea después de las tablas y nace vacía: sólo recibe lo que se inserte desde entonces. Si escribe en otra tabla con TO, marca también esa tabla para llevarte sus filas.

Si el destino es el mismo servidor que el origen y un objeto acabaría en su propia base, Migrar se queda apagado y un aviso dice por qué: con Reemplazar en destino, la copia borraría el original antes de leer sus filas.

Si el servidor que necesitas no aparece en el selector, añádelo primero en el Gestor de conexiones y vuelve a abrir Migración de datos.

Oracle

Con Oracle de destino no hay Omitir FK checks: Oracle no apaga las claves foráneas por sesión. Entre dos esquemas de Oracle, un esquema de destino que no existe se crea como usuario sin contraseña (NO AUTHENTICATION) y con cuota en su tablespace; las tablas llegan con el DDL de Oracle, sus filas en INSERT de varias filas que se confirman al ejecutarse, las fechas como literal TIMESTAMP y las claves foráneas al final. Oracle guarda los nombres en mayúsculas: entre familias, una tabla y sus columnas se emparejan también con las que sólo cambian en mayúsculas (CLIENTES con clientes).

Con una etiqueta de entorno: el destino lo protege la etiqueta de su perfil. Si confirma lo que escribe, la migración pregunta una vez antes de empezar, contando objetos, y la vista previa no pregunta; si es de solo lectura, no se escribe en él. Con una etiqueta de solo lectura en la conexión de esta pestaña, la herramienta no se ofrece.

Palabras clave: migrar, migration, copiar, mover, servidor destino, conexión destino, selector

Previsualizar SQL de migración

Revisa el SQL que se ejecutaría antes de migrar.

Dónde está: Migración de datos › Vista previa

Marca Vista previa y el botón pasa a ser Generar SQL: en lugar de ejecutar nada, Calíope escribe en el panel de salida el SQL que ejecutaría la migración, para que puedas revisarlo o copiarlo. Es el mismo guion que ejecuta la migración: CREATE DATABASE IF NOT EXISTS, el cambio a esa base, las claves foráneas apagadas con Omitir FK checks, con Reemplazar en destino, primero el DROP de todo lo marcado —lo que depende de las tablas, y las tablas hijas antes que sus madres—, después cada objeto, y los INSERT con Exportar datos. Las rutinas y los triggers van entre DELIMITER // y DELIMITER ;, así que el guion también se ejecuta tal cual en el Editor SQL con Ejecutar Script. En modo Vista previa no hace falta conectar el destino.

Las claves foráneas van al final, tras todas las tablas y sus filas.

Con un destino conectado, el guion empieza diciendo en comentarios lo que el destino no puede tener, y eso no va en él.

TiDB

Con TiDB el guion enciende allow_auto_random_explicit_insert antes de los INSERT y lo apaga al final, como la migración.

SQL Server

En SQL Server el guion crea la base y el esquema si faltan (IF DB_ID(…) IS NULL), no lleva DELIMITER —cada rutina va en su propio EXEC— y las filas con valor de identidad van entre SET IDENTITY_INSERT … ON y OFF.

PostgreSQL

En PostgreSQL el guion crea el esquema si falta (CREATE SCHEMA IF NOT EXISTS), apaga las claves foráneas con SET session_replication_role, crea antes de las tablas los tipos que usan, y no lleva DELIMITER: el cuerpo de una función va entre comillas $function$.

ClickHouse

En ClickHouse el guion no cambia de base —cada objeto lleva la suya delante—, no apaga claves foráneas, porque no las hay, y cada DROP lleva SYNC. Una columna Array, Map o Tuple va en el INSERT como JSONExtract('…', 'tipo').

Oracle

En Oracle el guion no lleva USE: cada objeto va con su esquema delante, y empieza con un bloque PL/SQL que crea el esquema de destino si no existe. No apaga claves foráneas: las deja para el final.

Palabras clave: preview, previsualizar, SQL preview, revisar antes de ejecutar

Comparar esquemas de bases de datos

Compara dos bases de datos del mismo servidor —tablas, vistas, rutinas, triggers y eventos— y genera el script de migración.

Dónde está: Espacio de Trabajo › Herramientas › Comparar esquemas

La herramienta de comparación de esquemas (Schema Diff) analiza dos bases de datos del mismo servidor y muestra exactamente qué ha cambiado en tablas, vistas, procedimientos, funciones y triggers.

MySQLMariaDBAurora

En MySQL y MariaDB compara también los eventos.

TiDB

En TiDB compara tablas, vistas y secuencias: TiDB no tiene procedimientos, funciones, disparadores ni eventos.

SQL Server

En SQL Server cada lado es un esquema de una base (demo.dbo), y los dos pueden vivir en bases distintas del mismo servidor. Los trabajos del Agent cuentan como eventos: se comparan por el guion que los crea, y llevar uno a la otra base sólo cambia la base de su paso; como su nombre es del servidor, crearlo otra vez en el mismo servidor choca con el que ya está, y lo dice sp_add_job.

PostgreSQL

En PostgreSQL cada lado es un esquema de la base conectada (demo, ventas).

Oracle

En Oracle cada lado es un esquema —un usuario, como DEMO o DEMO_R1— de la base a la que conectas, y compara también los paquetes, los tipos y las secuencias.

Cómo abrir Schema Diff:
Pulsa Comparar esquemas (ícono de flechas contrapuestas) en la barra lateral. Se abre en una nueva pestaña.

Uso básico:
1. Elige el Origen y el Destino en la barra superior. El guion cambia el origen hasta que coincida con el destino: lo que sólo tiene el destino se crea en el origen, y lo que sólo tiene el origen se elimina.
2. Pulsa Comparar. Calíope lee la definición de cada objeto en los dos lados, tal como la escribe el propio servidor.
3. Activa el toggle Solo cambios para ocultar lo que coincide.
4. El informe se agrupa por tipo de objeto. Despliega cualquier fila: en una tabla modificada verás cambio por cambio la definición que hay y la que quedará; en una vista o rutina modificada, las dos definiciones completas enfrentadas; en un objeto nuevo o eliminado, su DDL.
5. Pulsa Copiar SQL para llevarte el guion entero, o el botón de copiar de una fila para llevarte solo ese objeto.
6. Ejecútalo en el Editor SQL con Ejecutar Script. Con el Modo Seguro activado, el guion se detiene antes de llegar al servidor. Después vuelve a comparar: los dos lados deben salir idénticos.

MySQLMariaDBAurora

Las definiciones son el SHOW CREATE … de cada objeto, y el editor entiende los bloques DELIMITER con los que llegan rutinas y triggers.

TiDB

En TiDB las definiciones son el SHOW CREATE … de cada objeto, con los comentarios propios de TiDB (/*T![clustered_index] CLUSTERED */) tal como vienen: viajan en el script y el servidor los lee.

SQL Server

Las definiciones salen del catálogo (sys.sql_modules para vistas, rutinas y triggers). Cada vista, rutina y trigger va en su propio EXEC … sp_executesql, porque T-SQL lo quiere solo en su lote, así que el guion corre sin líneas GO.

PostgreSQL

Las definiciones son las que escribe el servidor con pg_get_viewdef, pg_get_functiondef y pg_get_triggerdef.

Oracle

Las definiciones son las que escribe el servidor con DBMS_METADATA.GET_DDL, sin almacenamiento ni tablespace. Antes de comparar se quita lo que es valor de fábrica: el ENABLE de cada restricción y las opciones por omisión de una identidad o de una secuencia.

Qué genera para las tablas:

MySQLMariaDBAuroraTiDB

- CREATE TABLE IF NOT EXISTS completo para las que faltan en el origen, con columnas, índices y opciones.
- DROP TABLE IF EXISTS para las que sobran.
- ALTER TABLE con ADD/DROP/MODIFY COLUMN conservando tipo, nulabilidad, valor por defecto, comentario, juego de caracteres y expresión de columna generada.
- Altas y bajas de clave primaria, índices y restricciones CHECK, y cambios de opciones (ENGINE, DEFAULT CHARSET, COLLATE, ROW_FORMAT, COMMENT).

SQL Server

- IF OBJECT_ID(…) IS NULL CREATE TABLE para las que faltan en el origen, con columnas, claves y restricciones, y un CREATE INDEX por cada índice.
- DROP TABLE IF EXISTS para las que sobran.
- ALTER TABLE con ADD, ALTER COLUMN y DROP COLUMN; antes de quitar una columna, el guion quita la restricción de valor por defecto que cuelga de ella.
- Altas y bajas de clave primaria, índices y restricciones CHECK.

PostgreSQL

- CREATE TABLE IF NOT EXISTS para las que faltan en el origen, con columnas y restricciones, y un CREATE INDEX por cada índice.
- DROP TABLE IF EXISTS para las que sobran.
- ALTER TABLE con ADD COLUMN, DROP COLUMN y ALTER COLUMN … TYPE, SET/DROP NOT NULL y SET/DROP DEFAULT.
- Altas y bajas de clave primaria, índices y restricciones CHECK, y el comentario de la tabla (COMMENT ON TABLE).

Oracle

- CREATE TABLE IF NOT EXISTS para las que faltan en el origen, con columnas, clave primaria, restricciones UNIQUE y CHECK y su particionado, y un CREATE INDEX por cada índice. Un índice espacial va precedido de sus metadatos (USER_SDO_GEOM_METADATA), sin los que el servidor no lo crea.
- DROP TABLE IF EXISTS … CASCADE CONSTRAINTS PURGE para las que sobran.
- ALTER TABLE con ADD, DROP COLUMN y MODIFY, que escribe sólo lo que cambia: el tipo, el valor por defecto o la nulabilidad.
- Altas y bajas de clave primaria, índices y restricciones, y los comentarios de la tabla y de sus columnas (COMMENT ON).

Qué genera para el resto de objetos:
Una vista o una rutina no se puede parchear por partes: si su definición difiere, el guion la rehace con la del destino, reescribiendo las referencias al esquema de origen para que apunte al sitio correcto.

MySQLMariaDBAuroraTiDB

La rehace con DROP + CREATE.

SQL Server

La rehace con CREATE OR ALTER, que aceptan vistas, procedimientos, funciones y triggers.

PostgreSQL

La rehace con CREATE OR REPLACE; un trigger o una vista materializada, que no lo tienen, se eliminan y se vuelven a crear.

Oracle

La rehace con el CREATE OR REPLACE que ya trae su DDL; una secuencia o una vista materializada, que no lo tienen, se eliminan y se vuelven a crear. Un trigger se crea sobre la tabla del esquema que se repara.

Orden del guion:
Primero las tablas; después las claves foráneas, en su propio bloque, porque al crear varias tablas el orden alfabético no respeta las dependencias; luego el resto de objetos por tipo, y dentro de cada tipo ordenados por dependencias — una vista construida sobre otra se emite después de ella.

MySQLMariaDBAuroraSQL ServerTiDB

Antes del primer objeto que no es una tabla, el guion fija la base activa con un USE.

PostgreSQL

Antes de las tablas van los tipos propios del esquema, con los que se declaran sus columnas.

PostgreSQL

Compara también las secuencias sueltas —una distinta se escribe con ALTER SEQUENCE, que no la devuelve a su comienzo— y, con la extensión pg_cron, sus trabajos en el esquema cron.

Oracle

Oracle no tiene USE: cada sentencia va cualificada con el esquema que se repara. Antes de las tablas van los tipos de objeto (CREATE TYPE) con los que se declaran sus columnas.

Lo que se ignora a propósito:

MySQLMariaDBAuroraTiDB

El contador de AUTO_INCREMENT, que avanza con cada inserción y nunca coincide entre dos copias.

TiDB

Tampoco el AUTO_RANDOM_BASE de TiDB, el mismo contador para una clave AUTO_RANDOM.

SQL ServerPostgreSQLOracle

El valor actual de una columna de identidad, que avanza con cada inserción y nunca coincide entre dos copias.

Oracle

Tampoco el valor actual de una secuencia (START WITH).

Lo que no cubre:
Las columnas de una tabla existente no se reordenan, y una columna renombrada se ve como una baja más un alta. La comparación de vistas, rutinas y triggers es textual, así que un simple cambio de formato cuenta como diferencia.

MySQLMariaDBAurora

Un cambio de particionado se detecta y se anota como aviso, pero no se convierte en SQL: reparticionar reescribe la tabla entera. Un cambio de DEFINER también cuenta como diferencia, y en MariaDB el DDL de un trigger es el texto literal con el que se escribió. Un evento con hora de inicio distinta también difiere, porque esa hora forma parte de su definición.

TiDB

También en TiDB un cambio de particionado se detecta y se anota como aviso, pero nunca se convierte en SQL, y un cambio de DEFINER de una vista cuenta como diferencia.

PostgreSQL

Los tipos propios —ENUM, dominios, tipos compuestos— se comparan como una vista, en su propio grupo Tipos. El guion crea los que faltan antes de las tablas que los usan y elimina al final del todo los que sólo tiene el origen. Un ENUM que sólo ha ganado etiquetas al final se actualiza con ALTER TYPE … ADD VALUE; cualquier otro cambio de un tipo queda en el guion como una nota para hacerlo a mano, porque rehacer un tipo en uso obliga a reescribir cada columna que lo usa. Los tipos que crea una extensión, como los de PostGIS, quedan fuera: los trae su CREATE EXTENSION.

Oracle

Un tipo de objeto en uso que difiere y un cambio de particionado quedan en el guion como nota para hacerlos a mano, y lo mismo poner una identidad a una columna que ya existe, que el servidor no admite. Una restricción con nombre de sistema (SYS_C…) se empareja por su definición.

Revisa siempre el script antes de ejecutarlo en producción.

Caso de uso típico:
Antes de un despliegue, comparar producción (origen) con el esquema de desarrollo (destino): el guion lleva producción a lo que desarrollo ya tiene, sin escribirlo a mano.

Disponible en macOS, iPad, iPhone y Apple Vision Pro.

ClickHouse

En ClickHouse compara tablas y vistas a partir de su SHOW CREATE. Columnas, índices de salto, proyecciones, restricciones, TTL, SETTINGS y el comentario se sincronizan con ALTER TABLE; un cambio de motor, ORDER BY, PARTITION BY, PRIMARY KEY o SAMPLE BY no cabe en un ALTER, así que sale en el guion como un comentario que dice que hay que recrear la tabla. Las vistas materializadas y los diccionarios no se comparan, y el motor no tiene procedimientos ni triggers.

Palabras clave: schema diff, comparar, esquema, alter table, migración, diferencias, ADD COLUMN, DROP COLUMN, MODIFY COLUMN, SHOW CREATE TABLE, CREATE TABLE, índices, claves foráneas, particionado, solo cambios