Cette page décrit Calíope 1.7, la version que je construis en ce moment. La 1.6 est sur l'App Store pour Mac, iPad, iPhone, Apple Watch, Apple TV et Apple Vision Pro. Le changelog indique dans quelle version chaque fonction est arrivée.

Ajoute un bouton « Ouvrir dans Calíope » à chaque sujet. Ne fonctionne qu'avec l'app installée.

Migration de données

Migrer des objets entre serveurs

Copiez tables, vues, routines, déclencheurs et événements vers un autre serveur, ou vers une autre base du même serveur.

Où le trouver : Espace de travail › Outils › Migration de données

Ouvrez Migration de données depuis la barre latérale du workspace. Elle copie tables, vues, routines, déclencheurs et événements de cette connexion vers un autre serveur, ou vers une autre base du même serveur.

Choisissez quoi copier dans l’arborescence de gauche. Son en-tête a un filtre par nom : saisissez une partie du nom d’une base ou d’un objet pour restreindre la liste sans déplier base par base. Les objets sont regroupés par type (Tables, Vues, Routines, Déclencheurs et Événements) ; cliquer sur un objet le coche, et la case de chaque base coche ou décoche tout son contenu, avec à côté le nombre d’objets cochés sur le total. Effacer vide la sélection. Calíope fixe l’ordre — tables, vues, routines, déclencheurs et événements — pour que chaque objet trouve déjà créé ce dont il dépend.

Choisissez la destination. À côté de Destination :, ouvrez Choisir le serveur cible, choisissez l’une des connexions enregistrées dans le Gestionnaire de connexions et cliquez sur Connecter. Dans Dans la base, saisissez la base où arriveront les objets ; vide, chaque objet garde la base qu’il a à la source. Calíope crée cette base si elle n’existe pas, et réécrit les références d’une vue pour qu’elle lise depuis celle-ci.

Options : Remplacer à destination supprime tout ce qui est coché avant de créer quoi que ce soit —d’abord ce qui dépend des tables, et les tables filles avant leurs mères—, donc relancer la même migration est sans risque ; Exporter les données copie les lignes de chaque table ; Ignorer les vérifications FK désactive la vérification des clés étrangères pendant le chargement de chaque objet, pour que les tables puissent arriver dans n’importe quel ordre.

Cliquez sur Migrer. Le journal donne une ligne par objet, avec la base où il est allé et, pour une table, les lignes copiées. Arrêter s’arrête entre un objet et le suivant.

Les clés étrangères des tables copiées sont créées à la fin, une fois toutes les tables présentes avec leurs lignes : l'ordre d'arrivée n'a plus d'importance.

Entre familles de moteurs différentes, un avertissement à côté de Migrer le signale avant toute exécution : le DDL d'un moteur n'est pas compris par l'autre, donc rien n'est créé. Seules les lignes sont copiées, vers des tables du même nom qui existent déjà dans la destination, en appariant les colonnes par nom ; une table que la destination n'a pas, ou un objet qui n'est pas une table, est ignoré et le journal l'indique.

SQL Server

Une colonne IDENTITY conserve ses valeurs (Calíope active IDENTITY_INSERT pendant la copie), mais pas son compteur : dans la destination, la ligne suivante repart de la valeur la plus haute copiée. Chaque objet arrive dans son schéma, créé s'il n'existe pas. Avec seulement un nom de base dans Dans la base, chaque objet garde son schéma : demo.dbo va dans copia.dbo, et demo.rrhh dans copia.rrhh.

PostgreSQL

Ici, une base est un schéma de la base connectée : Dans la base nomme le schéma où vont les objets, et il est créé s’il n’existe pas. Les types qu’utilisent les tables copiées —un ENUM, un domaine— sont créés d’abord ; un type qui existe déjà dans la destination est conservé tel quel, car le refaire obligerait à supprimer chaque colonne qui l’utilise. Le search_path d’une fonction copiée pointe vers le schéma de destination, donc ses déclencheurs écrivent là et non dans la source.

ClickHouse

Chaque table est créée à partir du DDL que garde le serveur —moteur, PARTITION BY, ORDER BY, TTL et SETTINGS compris—, et il n’y a ni clés étrangères ni Ignorer les vérifications FK. Les lignes partent dans des INSERT de cent en cent, et une colonne Array, Map ou Tuple arrive avec son type. Une vue matérialisée est créée après les tables et naît vide : elle ne reçoit que ce qui est inséré à partir de là. Si elle écrit dans une autre table avec TO, cochez aussi cette table pour emporter ses lignes.

Si la destination est le même serveur que la source et qu’un objet arriverait dans sa propre base, Migrer reste désactivé et un avertissement explique pourquoi : avec Remplacer à destination, la copie supprimerait l’original avant d’en lire les lignes.

Si le serveur dont vous avez besoin n’apparaît pas dans le sélecteur, ajoutez-le d’abord dans le Gestionnaire de connexions et rouvrez Migration de données.

Oracle

Avec Oracle comme destination il n’y a pas Ignorer les vérifications FK : Oracle ne désactive pas les clés étrangères par session. Entre deux schémas Oracle, un schéma de destination qui n’existe pas est créé comme utilisateur sans mot de passe (NO AUTHENTICATION) et avec un quota sur son tablespace ; les tables arrivent avec le DDL d’Oracle, leurs lignes en INSERT de plusieurs lignes validés à l’exécution, les dates en littéraux TIMESTAMP et les clés étrangères à la fin. Oracle enregistre les noms en majuscules : entre familles, une table et ses colonnes sont aussi appariées avec celles qui ne diffèrent que par la casse (CLIENTES avec clientes).

Avec une étiquette d’environnement : la destination est protégée par l’étiquette de son profil. Si elle confirme les écritures, la migration demande une fois avant de commencer, en comptant les objets, et l’aperçu ne demande pas ; si elle est en lecture seule, rien n’y est écrit. Avec une étiquette en lecture seule sur la connexion de cet onglet, l’outil n’est pas proposé.

Mots-clés : migrer, migration, copier, déplacer, serveur cible, connexion cible, sélecteur

Prévisualiser le SQL de migration

Examinez le SQL qui serait exécuté avant de migrer.

Où le trouver : Migration de données › Aperçu

Cochez Aperçu et le bouton devient Générer le SQL : au lieu d’exécuter quoi que ce soit, Calíope écrit dans le panneau de sortie le SQL que la migration exécuterait, pour que vous puissiez le vérifier ou le copier. C’est le même script que celui de la migration : CREATE DATABASE IF NOT EXISTS, le passage à cette base, les clés étrangères désactivées avec Ignorer les vérifications FK, avec Remplacer à destination, d’abord le DROP de tout ce qui est coché —ce qui dépend des tables, puis les tables filles avant leurs mères—, ensuite chaque objet, et les INSERT avec Exporter les données. Les routines et les déclencheurs sont placés entre DELIMITER // et DELIMITER ;, donc le script s’exécute aussi tel quel dans l’Éditeur SQL avec Exécuter le script. En mode Aperçu, aucune connexion à la destination n’est nécessaire.

Les clés étrangères viennent à la fin, après toutes les tables et leurs lignes.

SQL Server

Dans SQL Server, le script crée la base et le schéma s'ils manquent (IF DB_ID(…) IS NULL), n'a pas de DELIMITER —chaque routine va dans son propre EXEC— et les lignes avec une valeur d'identité vont entre SET IDENTITY_INSERT … ON et OFF.

PostgreSQL

Dans PostgreSQL, le script crée le schéma s’il manque (CREATE SCHEMA IF NOT EXISTS), désactive les clés étrangères avec SET session_replication_role, crée avant les tables les types qu’elles utilisent, et n’a pas de DELIMITER : le corps d’une fonction va entre guillemets $function$.

ClickHouse

Dans ClickHouse le script ne change pas de base —chaque objet porte la sienne devant—, ne désactive pas les clés étrangères, puisqu’il n’y en a pas, et chaque DROP porte SYNC. Une colonne Array, Map ou Tuple va dans l’INSERT sous la forme JSONExtract('…', 'type').

Oracle

Avec Oracle le script n’a pas de USE : chaque objet porte son schéma devant, et il commence par un bloc PL/SQL qui crée le schéma de destination s’il n’existe pas. Il ne désactive pas les clés étrangères : il les laisse pour la fin.

Mots-clés : aperçu, preview, SQL preview, vérifier avant d'exécuter

Comparer des schémas de bases de données

Comparez deux bases de données du même serveur — tables, vues, routines, déclencheurs et événements — et générez le script de migration.

Où le trouver : Espace de travail › Outils › Comparaison de schémas

L'outil de comparaison de schémas (Schema Diff) analyse deux bases de données du même serveur et montre exactement ce qui a changé dans les tables, vues, procédures, fonctions et déclencheurs.

MySQLMariaDBAurora

Sous MySQL et MariaDB, il compare aussi les événements.

SQL Server

Sous SQL Server, chaque côté est un schéma d'une base (demo.dbo), et les deux peuvent se trouver dans des bases différentes du même serveur.

PostgreSQL

Sous PostgreSQL, chaque côté est un schéma de la base connectée (demo, ventas).

Oracle

Dans Oracle chaque côté est un schéma —un utilisateur, comme DEMO ou DEMO_R1— de la base à laquelle vous êtes connecté, et l’outil compare aussi les paquetages, les types et les séquences.

Ouvrir Schema Diff :
Cliquez sur Comparaison de schémas (icône de flèches opposées) dans la barre latérale. L'outil s'ouvre dans un nouvel onglet.

Utilisation de base :
1. Choisissez la Source et la Cible dans la barre supérieure. Le script modifie la source jusqu'à ce qu'elle corresponde à la cible : ce que seule la cible possède est créé dans la source, et ce que seule la source possède est supprimé.
2. Cliquez sur Comparer. Calíope lit la définition de chaque objet des deux côtés, telle que le serveur lui-même l'écrit.
3. Activez l'option Changements uniquement pour masquer ce qui coïncide.
4. Le rapport est groupé par type d'objet. Dépliez n'importe quelle ligne : une table modifiée montre, changement par changement, la définition actuelle et celle qui la remplacera ; une vue ou une routine modifiée montre les deux définitions complètes ; un objet nouveau ou supprimé montre son DDL.
5. Cliquez sur Copier le SQL pour tout le script, ou sur le bouton de copie d'une ligne pour ce seul objet.
6. Exécutez-le dans l'Éditeur SQL avec Exécuter le script. Avec le Mode sécurisé activé, le script s'arrête avant d'atteindre le serveur. Comparez ensuite de nouveau : les deux côtés doivent ressortir identiques.

MySQLMariaDBAurora

Les définitions sont le SHOW CREATE … de chaque objet, et l'éditeur comprend les blocs DELIMITER dans lesquels arrivent routines et déclencheurs.

SQL Server

Les définitions viennent du catalogue (sys.sql_modules pour les vues, routines et déclencheurs). Chaque vue, routine et déclencheur part dans son propre EXEC … sp_executesql, car T-SQL le veut seul dans son lot : le script s'exécute donc sans lignes GO.

PostgreSQL

Les définitions sont celles que le serveur écrit avec pg_get_viewdef, pg_get_functiondef et pg_get_triggerdef.

Oracle

Les définitions sont celles qu’écrit le serveur avec DBMS_METADATA.GET_DDL, sans stockage ni tablespace. Avant la comparaison, ce qui est une valeur d’usine est retiré, comme le ENABLE de chaque contrainte et les options par défaut d’une identité ou d’une séquence.

Ce qui est généré pour les tables :

MySQLMariaDBAurora

- Un CREATE TABLE IF NOT EXISTS complet pour celles qui manquent dans la source, avec colonnes, index et options.
- DROP TABLE IF EXISTS pour celles qui sont en trop.
- ALTER TABLE avec ADD/DROP/MODIFY COLUMN, en conservant le type, la nullabilité, la valeur par défaut, le commentaire, le jeu de caractères et l'expression d'une colonne générée.
- Ajouts et suppressions de clé primaire, d'index et de contraintes CHECK, ainsi que les changements d'options (ENGINE, DEFAULT CHARSET, COLLATE, ROW_FORMAT, COMMENT).

SQL Server

- IF OBJECT_ID(…) IS NULL CREATE TABLE pour celles qui manquent dans la source, avec colonnes, clés et contraintes, et un CREATE INDEX pour chaque index.
- DROP TABLE IF EXISTS pour celles qui sont en trop.
- ALTER TABLE avec ADD, ALTER COLUMN et DROP COLUMN ; avant de supprimer une colonne, le script supprime la contrainte de valeur par défaut qui en dépend.
- Ajouts et suppressions de clé primaire, d'index et de contraintes CHECK.

PostgreSQL

- CREATE TABLE IF NOT EXISTS pour celles qui manquent dans la source, avec colonnes et contraintes, et un CREATE INDEX pour chaque index.
- DROP TABLE IF EXISTS pour celles qui sont en trop.
- ALTER TABLE avec ADD COLUMN, DROP COLUMN et ALTER COLUMN … TYPE, SET/DROP NOT NULL et SET/DROP DEFAULT.
- Ajouts et suppressions de clé primaire, d'index et de contraintes CHECK, et le commentaire de la table (COMMENT ON TABLE).

Oracle

- CREATE TABLE IF NOT EXISTS pour celles qui manquent dans la source, avec les colonnes, la clé primaire, les contraintes UNIQUE et CHECK et leur partitionnement, et un CREATE INDEX par index. Un index spatial est précédé de ses métadonnées (USER_SDO_GEOM_METADATA), sans lesquelles le serveur ne le crée pas.
- DROP TABLE IF EXISTS … CASCADE CONSTRAINTS PURGE pour celles en trop.
- ALTER TABLE avec ADD, DROP COLUMN et MODIFY, qui n’écrit que ce qui change, soit le type, la valeur par défaut ou la nullabilité.
- Ajout et suppression de la clé primaire, des index et des contraintes, et les commentaires de la table et de ses colonnes (COMMENT ON).

Ce qui est généré pour le reste :
Une vue ou une routine ne se corrige pas par morceaux : si sa définition diffère, le script la refait à partir de la cible, en réécrivant les références au schéma d'origine pour qu'elle pointe au bon endroit.

MySQLMariaDBAurora

Il la refait avec DROP + CREATE.

SQL Server

Il la refait avec CREATE OR ALTER, qu'acceptent les vues, procédures, fonctions et déclencheurs.

PostgreSQL

Il la refait avec CREATE OR REPLACE ; un déclencheur ou une vue matérialisée, qui ne l'ont pas, sont supprimés puis recréés.

Oracle

Il le recrée avec le CREATE OR REPLACE que son DDL contient déjà. Une séquence ou une vue matérialisée, qui n’en ont pas, sont supprimées puis recréées. Un déclencheur est créé sur la table du schéma qu’on répare.

Ordre du script :
D'abord les tables ; ensuite les clés étrangères, dans leur propre bloc, car lorsque plusieurs tables sont créées l'ordre alphabétique ne respecte pas les dépendances ; puis les autres objets par type, chaque type ordonné par dépendances — une vue construite sur une autre est émise après elle.

MySQLMariaDBAuroraSQL Server

Avant le premier objet qui n'est pas une table, le script fixe la base active avec un USE.

PostgreSQL

Avant les tables viennent les types propres du schéma, avec lesquels leurs colonnes sont déclarées.

Oracle

Oracle n’a pas de USE et chaque instruction est qualifiée par le schéma qu’on répare. Avant les tables viennent les types d’objet (CREATE TYPE) avec lesquels leurs colonnes sont déclarées.

Ignoré à dessein :

MySQLMariaDBAurora

Le compteur AUTO_INCREMENT, qui avance à chaque insertion et ne coïncide jamais entre deux copies.

SQL ServerPostgreSQLOracle

La valeur actuelle d'une colonne d'identité, qui avance à chaque insertion et ne coïncide jamais entre deux copies.

Oracle

Ni la valeur courante d’une séquence (START WITH).

Ce qui n'est pas couvert :
Les colonnes d'une table existante ne sont pas réordonnées, et une colonne renommée apparaît comme une suppression suivie d'un ajout. Les vues, routines et déclencheurs sont comparés textuellement : un simple changement de mise en forme compte comme une différence.

MySQLMariaDBAurora

Un changement de partitionnement est détecté et signalé, mais jamais traduit en SQL : repartitionner réécrit toute la table. Un changement de DEFINER compte aussi comme une différence, et sous MariaDB le DDL d'un déclencheur est le texte littéral avec lequel il a été écrit. Un événement dont l'heure de début diffère est également différent, car cette heure fait partie de sa définition.

PostgreSQL

Les types propres — ENUM, domaines, types composites — sont comparés comme une vue, dans leur propre groupe Types. Le script crée ceux qui manquent avant les tables qui les utilisent et supprime tout à la fin ceux que seule la source possède. Un ENUM qui a seulement gagné des étiquettes à la fin est mis à jour avec ALTER TYPE … ADD VALUE ; tout autre changement d'un type reste dans le script comme une note à appliquer à la main, car recréer un type utilisé oblige à réécrire chaque colonne qui l'utilise. Les types créés par une extension, comme ceux de PostGIS, sont laissés de côté : c'est son CREATE EXTENSION qui les apporte.

Oracle

Un type d’objet utilisé qui diffère et un changement de partitionnement restent dans le script comme une note à traiter à la main, tout comme l’ajout d’une identité à une colonne existante, que le serveur refuse. Une contrainte au nom système (SYS_C…) est appariée par sa définition.

Vérifiez toujours le script avant de l'exécuter en production.

Cas d'usage typique :
Avant un déploiement, comparer la production (source) avec le schéma de développement (cible) : le script amène la production à ce que le développement possède déjà, sans l'écrire à la main.

Disponible sur macOS, iPad, iPhone et Apple Vision Pro.

ClickHouse

Dans ClickHouse, il compare les tables et les vues à partir de leur SHOW CREATE. Colonnes, index de saut, projections, contraintes, TTL, SETTINGS et commentaire se synchronisent avec ALTER TABLE ; un changement de moteur, d'ORDER BY, de PARTITION BY, de PRIMARY KEY ou de SAMPLE BY ne tient pas dans un ALTER, donc il sort dans le script sous forme de commentaire disant qu'il faut recréer la table. Les vues matérialisées et les dictionnaires ne sont pas comparés, et le moteur n'a ni procédures ni déclencheurs.

Mots-clés : schema diff, comparer, schéma, alter table, migration, différences, ADD COLUMN, DROP COLUMN, MODIFY COLUMN, SHOW CREATE TABLE, CREATE TABLE, index, clés étrangères, partitionnement, modifications uniquement