Datenbankmigrationen in Go (Golang): vollständige Anleitung
Bei der Entwicklung von Webanwendungen in Go entsteht früher oder später die Notwendigkeit, die Datenbankstruktur zu ändern: neue Tabellen hinzufügen, vorhandene Spalten ändern oder Indizes erstellen. Die manuelle Ausführung von SQL-Skripten in verschiedenen Umgebungen (Entwicklung, Staging, Produktion) führt zu Fehlern und Desynchronisation. Die Lösung für dieses Problem sind Datenbankmigrationen.
In Go gibt es mehrere ausgereifte Bibliotheken zur Verwaltung von Migrationen. In diesem Artikel werden wir die beiden beliebtesten im Detail analysieren: golang-migrate/migrate und pressly/goose, und auch Beispiele für ihre Verwendung geben.
Was sind Migrationen und warum werden sie benötigt?
Eine Migration ist ein versionierter Satz von SQL-Befehlen (oder Go-Code), der sequentiell auf die Datenbank angewendet wird. Jede Migration hat eine eindeutige Kennung (normalerweise ein Zeitstempel oder eine Nummer) und kann angewendet (up) oder zurückgesetzt (down) werden.
Die wichtigsten Vorteile:
- Automatisierung von DB-Schemaänderungen
- Reproduzierbarkeit – gleiches Ergebnis in jeder Umgebung
- Möglichkeit des Zurücksetzens von Änderungen
- Speicherung des Änderungsverlaufs im Code (VCS-freundlich)
1. Bibliothek golang-migrate/migrate
Dies ist die beliebteste Bibliothek für Migrationen in Go. Unterstützt PostgreSQL, MySQL, SQLite, MongoDB und andere DBMS. Migrationen können sowohl in reinem SQL als auch in Go geschrieben werden.
Installation
go get -u github.com/golang-migrate/migrate/v4Struktur der Migrationsdateien
Die Dateien befinden sich im Ordner migrations/ und werden nach folgendem Schema benannt:
{timestamp}_{title}.up.sql{timestamp}_{title}.down.sqlBeispiel:
migrations/ 000001_create_users_table.up.sql 000001_create_users_table.down.sql 000002_add_email_to_users.up.sql 000002_add_email_to_users.down.sqlBeispiel einer SQL-Migration
Datei 000001_create_users_table.up.sql:
CREATE TABLE IF NOT EXISTS users ( id SERIAL PRIMARY KEY, name VARCHAR(255) NOT NULL, created_at TIMESTAMP DEFAULT NOW());Datei 000001_create_users_table.down.sql:
DROP TABLE IF EXISTS users;Anwendung von Migrationen aus Go-Code
package main
import ( "github.com/golang-migrate/migrate/v4" _ "github.com/golang-migrate/migrate/v4/database/postgres" _ "github.com/golang-migrate/migrate/v4/source/file")
func main() { m, err := migrate.New( "file://migrations", "postgres://user:password@localhost:5432/dbname?sslmode=disable", ) if err != nil { panic(err) }
// Alle verfügbaren Migrationen anwenden (Up) if err := m.Up(); err != nil && err != migrate.ErrNoChange { panic(err) }
// Letzte Migration zurücksetzen (Down) // if err := m.Steps(-1); err != nil { // panic(err) // }}CLI-Tool migrate
Es ist auch ein Befehlszeilentool verfügbar:
migrate create -ext sql -dir migrations -seq create_users_tablemigrate -path migrations -database "postgres://..." upmigrate -path migrations -database "postgres://..." down 12. Bibliothek pressly/goose
Goose ist ein weiteres beliebtes Tool, das ursprünglich als Analogon zu ActiveRecord-Migrationen aus Ruby on Rails entwickelt wurde. Es unterstützt SQL- und Go-Migrationen sowie ein integriertes CLI.
Installation
go get -u github.com/pressly/goose/v3Dateistruktur
Die Dateien werden als {timestamp}_{title}.sql benannt (ohne Aufteilung in up/down – alles in einer Datei über Kommentare):
migrations/ 20240101120000_create_users_table.sql 20240102150000_add_email_to_users.sqlBeispiel einer SQL-Migration
Auch in der Bibliothek
tsup für TypeScript: Komplettguide mit Beispielen
Realm Kotlin für Kotlin: Vollständiges Tutorial mit Beispielen
Protocol Buffers für Java: Komplette Anleitung mit Beispielen
Prometheus-Metriken in TypeScript: Vollständiger Leitfaden zu client.js
OAuth-Client für PHP: Integration mit Google, GitHub und VK