Guida all'uso di Go Migrate

1. Panoramica di Go Migrate

Go Migrate è uno strumento per gestire la migrazione del database scritto in linguaggio Go. Può essere utilizzato come interfaccia a riga di comando (CLI) o importato come libreria per progetti Go. Go Migrate può leggere file di migrazione da diverse fonti e applicarli al database nell'ordine corretto. Supporta vari driver di database e fonti di migrazione.

2. Versioni

Go Migrate supporta diverse versioni, tra cui:

  • Master: L'ultima versione, inclusi nuove funzionalità e correzioni di bug
  • v4: Versione stabile, adatta per gli ambienti di produzione
  • v3: Non più supportata e non dovrebbe essere utilizzata

3. Installazione

Per utilizzare Go Migrate, è necessario installare il pacchetto Go. Eseguire il seguente comando per l'installazione:

go get -u -d github.com/golang-migrate/migrate/v4
cd $GOPATH/src/github.com/golang-migrate/migrate/v4

4. Utilizzo di Go Migrate

Go Migrate può essere utilizzato tramite la CLI o come libreria nel progetto Go.

4.0. URL di Connessione al Database

Che si tratti di utilizzare la CLI o il codice Go, è necessario configurare gli URL del database per la connessione al database.

Formato URL:

dbdriver://username:password@host:port/dbname?param1=true&param2=false

Questo URL è un URL di connessione al database utilizzato per connettersi al database e specificare i parametri di connessione. Ecco una spiegazione per ciascuna parte:

  1. dbdriver://: Questo è l'identificatore del protocollo per il driver di database utilizzato per specificare quale driver di database utilizzare, ad esempio mysql.
  2. username:password: Questi sono l'username e la password utilizzati per l'autenticazione. Tipicamente, l'username e la password sono separati da due punti (:).
  3. @: Questo simbolo è utilizzato per separare l'username e la password dall'hostname e dalla porta.
  4. host:port: Questo è l'hostname e il numero di porta del server del database. L'hostname è l'indirizzo IP o il nome di dominio del server del database, e il numero di porta è la porta su cui il server del database è in ascolto.
  5. /dbname: Questo è il nome del database a cui connettersi.
  6. ?param1=true&param2=false: Questa parte sono i parametri di query utilizzati per specificare ulteriori parametri di connessione. In questo esempio, ci sono due parametri.

Questi parametri di query possono essere impostati in base ai requisiti specifici del driver di database e del server del database per configurare attributi o comportamenti specifici della connessione.

Parametri di Connessione Postgres

postgres://postgres:password@localhost:5432/example?sslmode=disable

Parametri di Connessione SQLite

sqlite3://percorso/verso/database?query

Parametri di Connessione MongoDB

mongodb://user:password@host:port/dbname?query

4.1 Utilizzo della CLI

4.1.1 Utilizzo Base

Per utilizzare la CLI, eseguire il seguente comando:

migrate -source file://percorso/verso/migrazioni -database postgres://localhost:5432/database up 2

Questo comando applica le migrazioni dalla fonte specificata al database dato. Il numero "2" indica il numero di migrazioni da applicare.

4.1.2 Utilizzo di Docker

Go Migrate può anche essere utilizzato con Docker. Eseguire il seguente comando:

docker run -v {{ directory di migrazione }}:/migrations --network host migrate/migrate -path=/migrations/ -database postgres://localhost:5432/database up 2

Questo comando esegue Go Migrate in un contenitore Docker e applica le migrazioni dalla fonte specificata al database dato.

3.2 Utilizzo nel tuo progetto Go

Per utilizzare Go Migrate nel tuo progetto Go, è necessario importare i pacchetti e le librerie richieste. Ecco un esempio:

import (
    "github.com/golang-migrate/migrate/v4"
    _ "github.com/golang-migrate/migrate/v4/database/postgres"
    _ "github.com/golang-migrate/migrate/v4/source/github"
)

func main() {
    m, err := migrate.New(
        "github://mattes:personal-access-token@mattes/migrate_test",
        "postgres://localhost:5432/database?sslmode=enable")
    m.Steps(2)
}

Questo codice inizializza Go Migrate con la sorgente e il database specificati, quindi applica 2 migrazioni utilizzando il metodo Steps.

Se si desidera utilizzare un client di database esistente, fare riferimento all'esempio seguente:

import (
    "database/sql"
    _ "github.com/lib/pq"
    "github.com/golang-migrate/migrate/v4"
    "github.com/golang-migrate/migrate/v4/database/postgres"
    _ "github.com/golang-migrate/migrate/v4/source/file"
)

func main() {
    db, err := sql.Open("postgres", "postgres://localhost:5432/database?sslmode=enable")
    driver, err := postgres.WithInstance(db, &postgres.Config{})
    m, err := migrate.NewWithDatabaseInstance(
        "file:///migrations",
        "postgres", driver)
    m.Up()
}

Questo codice importa i pacchetti richiesti e inizializza il client di database con il pacchetto sql. Quindi crea una nuova istanza di Go Migrate utilizzando il metodo NewWithDatabaseInstance, specificando la sorgente e il driver del database. Infine, applica la migrazione utilizzando il metodo Up.

4. Driver del database supportati

Go Migrate supporta diversi driver di database, tra cui:

  • PostgreSQL
  • PGX v4
  • PGX v5
  • Redshift
  • Ql
  • Cassandra
  • SQLite
  • SQLite3
  • SQLCipher
  • MySQL/MariaDB
  • Neo4j
  • MongoDB
  • CrateDB
  • Shell
  • Google Cloud Spanner
  • CockroachDB
  • YugabyteDB
  • ClickHouse
  • Firebird
  • MS SQL Server

5. Sorgenti di migrazione supportate

Go Migrate supporta diverse sorgenti di migrazione, tra cui:

  • File System: Legge le migrazioni dal file system locale.
  • io/fs: Legge le migrazioni utilizzando il pacchetto Go io/fs.
  • Go-Bindata: Legge le migrazioni dai dati binari incorporati utilizzando il pacchetto jteeuwen/go-bindata.
  • pkger: Legge le migrazioni dai dati binari incorporati utilizzando il pacchetto markbates/pkger.
  • GitHub: Legge le migrazioni da un repository remoto su GitHub.
  • GitHub Enterprise: Legge le migrazioni da un repository remoto su GitHub Enterprise.
  • Bitbucket: Legge le migrazioni da un repository remoto su Bitbucket.
  • Gitlab: Legge le migrazioni da un repository remoto su Gitlab.
  • AWS S3: Legge le migrazioni da Amazon Web Services S3.
  • Google Cloud Storage: Legge le migrazioni da Google Cloud Platform Storage.

A seconda dei requisiti del tuo progetto, puoi memorizzare i file di migrazione del database nelle sorgenti di archiviazione file supportate sopra menzionate.

6. File di migrazione

I file di migrazione in Go Migrate hanno formati specifici per il nome del file e il contenuto.

6.1 Formato del nome del file di migrazione

Ogni migrazione consiste di un file di migrazione "up" e un corrispondente file di migrazione "down". I nomi dei file di migrazione dovrebbero aderire al seguente formato:

{version}_{titolo}.up.{estensione}
{version}_{titolo}.down.{estensione}

versione è un numero univoco che rappresenta l'ordine in cui le migrazioni dovrebbero essere applicate. titolo è una descrizione facoltativa della migrazione. estensione dipende dal sistema di database utilizzato (ad es., per varianti SQL, utilizzare .sql).

6.2 Formato del contenuto della migrazione

Il contenuto dei file di migrazione varia a seconda del sistema di database, di solito coinvolge la scrittura diretta di SQL.

Ad esempio, i seguenti sono due file di migrazione:

  • 000001_create_users_table.up.sql
  • 000001_create_users_table.down.sql

File di migrazione 000001_create_users_table.up.sql

CREATE TABLE IF NOT EXISTS users(
   user_id serial PRIMARY KEY,
   username VARCHAR (50) UNIQUE NOT NULL,
   password VARCHAR (50) NOT NULL,
   email VARCHAR (300) UNIQUE NOT NULL
);

File di migrazione 000001_create_users_table.down.sql, il file di rollback viene utilizzato principalmente per annullare le operazioni precedenti.

DROP TABLE IF EXISTS users;

6.3 Reversibilità della migrazione

Scrivere migrazioni reversibili è considerata una pratica ottimale. Ciò significa che le migrazioni "up" e "down" dovrebbero essere in grado di eseguire qualsiasi versione, ricreando ed eliminando efficacemente lo stato del database.

Per garantire la reversibilità, ogni migrazione dovrebbe avere un corrispondente file di migrazione "up" e "down". Il file di migrazione "up" contiene le operazioni per applicare la migrazione, mentre il file di migrazione "down" contiene le operazioni per annullare la migrazione.

7. Utilizzo di MySQL

Go Migrate fornisce supporto per i database MySQL. Per connettersi a un database MySQL, l'URL del database deve essere nel seguente formato:

mysql://utente:password@tcp(host:port)/nomedb?query

L'URL può includere parametri di query, come ad esempio il nome della tabella di migrazione, i parametri TLS, ecc. Per una lista completa dei parametri di query, fare riferimento alla documentazione MySQL di Go Migrate.

7.1 Parametri di query dell'URL

  • x-migrations-table: Il nome della tabella di migrazione.
  • x-no-lock: Impostare su true per evitare le istruzioni GET_LOCK/RELEASE_LOCK. Utile per le versioni multi-master di MySQL.
  • x-statement-timeout: Annulla qualsiasi istruzione che supera il numero specificato di millisecondi.
  • dbname: Il nome del database a cui connettersi.
  • user: L'utente con cui effettuare l'accesso.
  • password: La password dell'utente.
  • host: L'host a cui connettersi.
  • port: La porta a cui associarsi.
  • tls: Parametri di connessione cifrata TLS/SSL.
  • x-tls-ca: La posizione del file CA (Certificato di Autorità).
  • x-tls-cert: La posizione del file del certificato del client.
  • x-tls-key: La posizione del file della chiave privata.
  • x-tls-insecure-skip-verify: Indica se utilizzare SSL.

7.2 Utilizzo con clienti esistenti

Se si intende utilizzare Go Migrate con un client MySQL esistente, assicurarsi di utilizzare il parametro multiStatements=true durante la creazione del client. Ecco un esempio:

package main

import (
    "database/sql"
    
    _ "github.com/go-sql-driver/mysql"
    "github.com/golang-migrate/migrate/v4"
    "github.com/golang-migrate/migrate/v4/database/mysql"
    _ "github.com/golang-migrate/migrate/v4/source/file"
)

func main() {
    db, _ := sql.Open("mysql", "utente:password@tcp(host:port)/nomedb?multiStatements=true")
    driver, _ := mysql.WithInstance(db, &mysql.Config{})
    m, _ := migrate.NewWithDatabaseInstance(
        "file:///migrations",
        "mysql", 
        driver,
    )
    
    m.Steps(2)
}

Questo codice importa i pacchetti richiesti, crea un client del database MySQL e inizializza Go Migrate con l'istanza del database. Quindi applica due migrazioni utilizzando il metodo Steps.