Datenbankmigrationen in Kotlin: Werkzeuge und praktische Beispiele

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Datenbankmigrationen in Kotlin: So verwalten Sie das Schema ohne Schmerz

\n

Bei der Entwicklung mit Kotlin, insbesondere in Verbindung mit der JVM, stellt sich früher oder später die Aufgabe, die Datenbankstruktur zwischen Entwicklern, Test- und Produktionsservern zu synchronisieren. Die manuelle Ausführung von SQL-Skripten führt zu Desynchronisation und Fehlern. Die Lösung sind Datenbankmigrationen. Dies ist eine automatisierte Methode, um Schemaänderungen zu versionieren: Erstellung von Tabellen, Hinzufügen von Spalten, Indizes und Triggern.

\n

In diesem Artikel betrachten wir drei beliebte Werkzeuge für Kotlin: Flyway, Liquibase und den integrierten Mechanismus Exposed. Sie erfahren, wie Sie diese in Ihr Projekt integrieren, Migrationen schreiben und typische Probleme vermeiden.

\n\n

Flyway: Einfachheit und Versionierung

\n

Flyway ist das beliebteste Werkzeug für Migrationen im JVM-Ökosystem. Es unterstützt Kotlin, Java und Groovy. Das Funktionsprinzip: Sie schreiben SQL-Skripte (oder Java/Kotlin-Klassen), und Flyway verfolgt mit Hilfe der Tabelle flyway_schema_history, welche bereits angewendet wurden.

\n

Einbindung in Gradle (Kotlin DSL):

\n
dependencies {\n    implementation("org.flywaydb:flyway-core:9.22.3")\n    // für PostgreSQL\n    implementation("org.flywaydb:flyway-database-postgresql:9.22.3")\n}
\n

Beispiel einer Migration V1__create_users.sql:

\n
CREATE TABLE users (\n    id SERIAL PRIMARY KEY,\n    username VARCHAR(50) NOT NULL UNIQUE,\n    email VARCHAR(100) NOT NULL,\n    created_at TIMESTAMP DEFAULT NOW()\n);\n\nCREATE INDEX idx_users_email ON users(email);
\n

Starten aus Kotlin-Code:

\n
import org.flywaydb.core.Flyway\n\nfun main() {\n    val flyway = Flyway.configure()\n        .dataSource("jdbc:postgresql://localhost:5432/mydb", "user", "pass")\n        .load()\n    flyway.migrate()\n}
\n

Vorteile:

\n
    \n
  • Minimale Konfiguration
  • \n
  • Unterstützung für Rollbacks (undo) in der kostenpflichtigen Version
  • \n
  • Funktioniert mit jedem SQL
  • \n
\n

Nachteile:

\n
    \n
  • Keine integrierte Schema-Validierung
  • \n
  • Schwieriges Management von Verzweigungen
  • \n
\n\n

Liquibase: Flexibilität und Deklarativität

\n

Liquibase bietet zwei Ansätze: Änderungen können in XML, YAML, JSON oder direkt in SQL beschrieben werden. Für Kotlin-Projekte ist das YAML-Format praktisch – es ist lesbar und leicht versionierbar.

\n

Hinzufügen in Gradle:

\n
dependencies {\n    implementation("org.liquibase:liquibase-core:4.24.0")\n}
\n

Beispiel einer Changelog-Datei db.changelog-master.yaml:

\n
databaseChangeLog:\n  - changeSet:\n      id: 1\n      author: developer\n      changes:\n        - createTable:\n            tableName: users\n            columns:\n              - column:\n                  name: id\n                  type: BIGINT\n                  autoIncrement: true\n                  constraints:\n                    primaryKey: true\n              - column:\n                  name: username\n                  type: VARCHAR(50)\n                  constraints:\n                    nullable: false\n                    unique: true\n              - column:\n                  name: email\n                  type: VARCHAR(100)\n        - createIndex:\n            indexName: idx_users_email\n            tableName: users\n            columns:\n              - column:\n                  name: email
\n

Starten aus Kotlin:

\n
import liquibase.Liquibase\nimport liquibase.database.jvm.JdbcConnection\nimport liquibase.resource.ClassLoaderResourceAccessor\nimport java.sql.DriverManager\n\nfun runMigrations() {\n    val connection = DriverManager.getConnection(\n        "jdbc:postgresql://localhost:5432/mydb", "user", "pass"\n    )\n    val database = DatabaseFactory.getInstance()\n        .findCorrectDatabaseImplementation(JdbcConnection(connection))\n    val liquibase = Liquibase("db.changelog-mas                    

Empfehlungen