Datenbankmigrationen in Kotlin: So verwalten Sie das Schema ohne Schmerz
\nBei 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.
\nIn 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\nFlyway: Einfachheit und Versionierung
\nFlyway 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.
Einbindung in Gradle (Kotlin DSL):
\ndependencies {\n implementation("org.flywaydb:flyway-core:9.22.3")\n // für PostgreSQL\n implementation("org.flywaydb:flyway-database-postgresql:9.22.3")\n}\nBeispiel einer Migration V1__create_users.sql:
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);\nStarten aus Kotlin-Code:
\nimport 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}\nVorteile:
\n- \n
- Minimale Konfiguration \n
- Unterstützung für Rollbacks (undo) in der kostenpflichtigen Version \n
- Funktioniert mit jedem SQL \n
Nachteile:
\n- \n
- Keine integrierte Schema-Validierung \n
- Schwieriges Management von Verzweigungen \n
Liquibase: Flexibilität und Deklarativität
\nLiquibase 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.
\nHinzufügen in Gradle:
\ndependencies {\n implementation("org.liquibase:liquibase-core:4.24.0")\n}\nBeispiel einer Changelog-Datei db.changelog-master.yaml:
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\nStarten aus Kotlin:
\nimport 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 Auch in der Bibliothek
ORM für Kotlin: Exposed vs Ktor vs Ktorm — Vergleich und Beispiele
Arbeiten mit Daten in Java: Überblick über Bibliotheken und Werkzeuge
yaml-cpp für C++: Komplette Anleitung mit Beispielen
gRPC für TypeScript: Bibliotheken, Einrichtung und Codebeispiele
Quartz.NET für C# (.NET): Komplettguide mit Beispielen