JDBMig: un approccio intuitivo

La migrazione dei dati tra diversi sistemi di database può essere complessa, soprattutto quando si hanno a che fare con differenze di schema e incongruenze nei tipi di dati. Per questo motivo ho deciso di sviluppare jdbmig, un'applicazione Java leggera e intuitiva, progettata per semplificare le migrazioni di database utilizzando JDBC. Che tu stia passando da MySQL a PostgreSQL, da SQLite a MariaDB o da qualsiasi altro database supportato da JDBC, JDBMIG semplifica il processo.

Perché JDBMIG?

A differenza degli strumenti di migrazione tradizionali che richiedono configurazioni estese o script complessi, JDBMIG è progettato pensando alla semplicità:

Facilità d'uso: configurazione minima richiesta: basta impostare un file di configurazione JSON ed eseguire la migrazione.
Ampia compatibilità: supporta qualsiasi database con un driver JDBC, inclusi MySQL, PostgreSQL, SQLite e MariaDB.
Installazione minima: applicazione leggera senza dipendenze complesse.

Per gli utenti interessati principalmente a utilizzare JDBMIG senza dover approfondire il codice sorgente, la cartella dist offre una comoda soluzione.

Utilizzo di JDBMIG senza il codice sorgente

  • Per utilizzare JDBMIG senza accedere al codice sorgente
  • Scarica il pacchetto di distribuzione
  • Accedi alla directory dist nel repository GitHub.
  • Scarica il file JDBMig.jar, che contiene l'applicazione compilata pronta per l'uso.
  • Prepara il file di configurazione:
  • Crea un file di configurazione JSON specificando i dettagli di connessione al database di origine e di destinazione, le tabelle da migrare e altre impostazioni. Un esempio di configurazione (config.json) è disponibile nel repository.
  • Eseguire la migrazione:
  • Aprire un terminale o un prompt dei comandi.
  • Accedere alla directory contenente il file JDBMig.jar scaricato.
  • Eseguire i comandi di esportazione e importazione secondo necessità

Esporta dati:

java -jar JDBMig.jar --export --config config/config.json --dataDir /percorso/dei/dati/esportati

Importa dati:

java -jar JDBMig.jar --import --config config/config.json --dataDir /percorso/dei/dati/esportati

--export: esporta i dati dal database di origine in file JSON.​
--import: importa i dati da File JSON nel database di destinazione.​
--config: specifica il percorso del file di configurazione.​

Altre opzioni includono:

--dataDir: specifica la directory in cui archiviare o leggere i file JSON.​
--useConn: specifica la connessione da utilizzare se sono definite più connessioni.

Questo approccio consente agli utenti di eseguire migrazioni di database senza sforzo, senza interagire con il codice sorgente.

All'interno della cartella dist/config sono presenti 3 file di configurazione di esempio. Il file config.json.EXAMPLE contiene la spiegazione di tutte le possibili chiavi di configurazione.

Esempio completo di file JSON di configurazione con commenti

{
"COME USARE QUESTO FILE": [
"----------- PROPRIETÀ OBBLIGATORIE -------------",
"- dataDir: il percorso in cui salvare o leggere il file JSON. I file devono corrispondere ai nomi delle tabelle nella sezione tables (i prodotti devono essere products.json).",
"dataDir può essere sovrascritto dall'argomento della riga di comando --dataDir [yourpath]",
"- tables: array di tabelle da esportare/importare",
"- connection: autoesplicativo. La proprietà [type] deve essere uguale alla proprietà [name] nella sezione driver",
"invece della proprietà connection è possibile definire più di una connessione e utilizzare",
"la proprietà useConn per selezionare quella desiderata. Questa proprietà può essere sovrascritta dalla riga di comando",
"- drivers: elenco dei driver e posizione del file jdbc library.jar",
"----------- ----------------------------- -------------",
"----------- PROPRIETÀ FACOLTATIVE -------------",
"- prettyPrint: crea tabelle JSON esportate con formato pretty",
"- fieldToLowerCase: trasforma tutti i nomi dei campi in minuscolo",
"----------- ----------------------------- -------------",
"Per le opzioni della riga di comando, eseguire: java -jar JDBMig-x.x.x.jar",
"Altre proprietà sono state ignorate e trattate come commenti"
],
"dataDir": "data/",
"fieldToLowerCase": false,
"prettyPrint": false,
"useConn": "SQLITE_connection",
"tables": [ "table1", "table2" ],
"EXAMPLE", "----------- ORACLE XE ----------------",
"ORACLE_connection": {
"type": "oracle",
"initStrings": [
"ALTER SESSION SET NLS_DATE_FORMAT='AAAA-MM-GG HH24:MI:SS'",
"ALTER SESSION SET NLS_TIMESTAMP_FORMAT='AAAA-MM-GG HH24:MI:SS'"
],
"jdbcUrl": "jdbc:oracle:thin:@//localhost:1521/XEPDB1",
"user": "user",
"password": "password"
},
"EXAMPLE", "----------- POSTGRES ----------------",
"POSTGRES_connection": {
"type": "postgres",
"initString": null,
"jdbcUrl": "jdbc:postgresql://localhost:5432/DATABASE_NAME?currentSchema=SCHEMA",
"user": "user",
"password": "password"
},
"EXAMPLE", "----------- MYSQL ----------------",
"MYSQL_connection": {
"type": "mysql",
"initString": null,
"jdbcUrl": "jdbc:mysql://localhost:3306/DATABASE_NAME",
"user": "user",
"password": "password"
},
"EXAMPLE", "----------- SQLITE ----------------",
"SQLITE_connection": {
"type": "sqlite",
"initString": null,
"jdbcUrl": "jdbc:sqlite:./sqlite/test.sqlite"
},
"SEZIONE DRIVER", "----------- DRIVER E VERSIONI SUPPORTATI ----------------",
"drivers": [
{"name": "mysql", "className": "com.mysql.jdbc.Driver", "jarFile": "lib/mysql-5.1.18.jar"},
{"name": "postgres", "className": "org.postgresql.Driver", "jarFile": "lib/pgsql-42.2.15.jar"},
{"name": "oracle", "className": "oracle.jdbc.driver.OracleDriver", "jarFile": "lib/ojdbc8.jar"},
{"name": "sqlite", "className": "org.sqlite.JDBC", "jarFile": "lib/sqlite-jdbc-3.32.3.8.jar"},
{"name": "informix", "className": "com.informix.jdbc.IfxDriver", "jarFile": "lib/ifxjdbc.jar"}
]
}

Ci sono 2 chiavi non documentate perché sperimentali.
Si inseriscono nella chiave [connection]:

beforeExecute e afterExecute: qui è possibile specificare il percorso di un file di script con comandi SQL specifici per la connessione.

beforeExecute: scripts/create_schema.sql,
afterExecute: scripts/defaultValues.sql


Ad esempio, per creare schemi prima dell'inizio dell'importazione o impostare i valori predefiniti per le tabelle dei campi al termine dell'importazione, o ancora meglio se si deve importare una grande quantità di dati, è È buona norma importare dati senza indici definiti e crearli al termine dell'importazione. Ad esempio, in Oracle, beforeExecute potrebbe essere utilizzato per creare le sequenze utilizzate dai campi autoincrementali prima, e afterExecute per aggiornare la sequenza con il numero di righe importate.

Esempio create_schema.sql

ALTER SESSION SET CURRENT_SCHEMA = test;
CREATE SEQUENCE CATEGORIES$_ID_SEQ START WITH 1 INCREMENT BY 1 MINVALUE 1 CACHE 20;
CREATE TABLE CATEGORIES (
ID NUMBER(10) DEFAULT CATEGORIES$_ID_SEQ.nextval NOT NULL,
NAME VARCHAR2(50 CHAR),
DESCRIPTION VARCHAR2(45 CHAR),
);

esempio di update_sequence.sql

DECLARE
max_rownum NUMERO;
INIZIO
ESEGUI IMMEDIATAMENTE 'ELIMINA SEQUENZA CATEGORIE$_ID_SEQ';
SELEZIONARE COALESCE(MAX(ID),0) INTO max_rownum DA CATEGORIE;
max_rownum := max_rownum + 1;
ESEGUI IMMEDIATAMENTE 'CREA SEQUENZA CATEGORIE$_ID_SEQ INIZIA CON '||max_rownum||' INCREMENT BY 1 MINVALUE 1 CACHE 20';
END

Limitazioni

Al momento, durante l'importazione, è possibile importare solo dati. Ciò significa che il database di destinazione deve esistere con la struttura di tutte le tabelle creata.

Approfondimenti sul codice sorgente

All'interno della cartella java è possibile trovare il codice sorgente di jdbmig. Il progetto è un progetto NetBeans con ANT. Esaminando i sorgenti, gli sviluppatori possono acquisire informazioni sui design pattern e sulle metodologie utilizzate in jdbmig e personalizzare o estendere le funzionalità dello strumento. Ad esempio, aggiungere la possibilità di creare lo schema sul database di destinazione durante l'importazione.

JDBMig.java: punto di ingresso che analizza gli argomenti della riga di comando e inoltra la richiesta di importazione o esportazione dei dati.

  • Export.java: questa classe gestisce l'estrazione dei dati dal database di origine. Stabilisce una connessione utilizzando i parametri JDBC forniti, recupera le tabelle specificate e scrive i dati in file JSON.
    Le funzionalità chiave includono:
  • Lettura di schemi e dati di tabelle.
  • Serializzazione dei dati in formato JSON.
  • Gestione delle connessioni e delle risorse del database.

Import.java: questa classe gestisce l'inserimento dei dati nel database di destinazione. Legge i dati dai file JSON generati dal processo di esportazione e li inserisce nelle tabelle corrispondenti del database di destinazione. Le funzionalità chiave includono:

  • Analisi dei file di dati JSON.
  • Mappatura dei dati sullo schema del database di destinazione.
  • Gestione delle conversioni dei tipi di dati e dei vincoli di integrità.

DynamicConnect.java: questa classe gestisce la connessione al database di destinazione in base ai dati forniti. driver.

DynamicDriver.java: questa classe è responsabile della mappatura dinamica del percorso o dell'URL del driver fornito al DriverManager; senza questa classe agnostica, questa utility non potrebbe esistere.

Esistono alcune classi di utility che analizzano i daticampi ed esportare o importare in un formato compatibile con JSON. Ad esempio, i campi blob vengono esportati in base64 con un prefisso speciale che ripristina il contenuto originale durante l'importazione. Per compatibilità, i campi data, data/ora e timestamp vengono esportati come stringa con un formato specifico. Per questo motivo, nel file di configurazione, sotto la chiave di connessione, è possibile utilizzare la chiave speciale initString per le impostazioni necessarie prima di avviare il processo di importazione o esportazione. Ad esempio, per importare all'interno di Oracle è necessario impostare un formato specifico.

 "EXAMPLE", "----------- ORACLE XE ----------------",
"ORACLE_connection": {
"type": "oracle",
"initStrings": [
"ALTER SESSION SET NLS_DATE_FORMAT='YYYY-MM-DD HH24:MI:SS'",
"ALTER SESSION SET NLS_TIMESTAMP_FORMAT='YYYY-MM-DD HH24:MI:SS'"
],
"jdbcUrl": "jdbc:oracle:thin:@//localhost:1521/XEPDB1",
"user": "user",
"password": "password"
}, 

Se sei interessato a saperne di più sul codice sorgente o a Per discutere con me dell'implementazione, di aspetti più tecnici per una migliore comprensione del codice, di come implementare nuove funzionalità o di come migliorare lo strumento, contattatemi.

Conclusione

jdbmig semplifica il processo di migrazione del database offrendo una soluzione semplice ed efficiente. Che siate sviluppatori esperti o principianti, questo strumento semplifica la transizione tra diversi sistemi di database.

Provatelo oggi stesso! Consultate il repository su GitHub e iniziate a migrare i vostri database senza problemi.