Czym jest Flyway?
Flyway jest narzędziem pozwalającym utrzymywać bazę danych w odpowiedniej wersji za pomocą migracji. Eliminuje to problemy z utrzymaniem spójności. Wprowadza również prosty, ale wystarczający, system kontroli wersji baz danych. Aplikacje wykorzystujące Flayway mogą same zarządzać wersją bazy danych na danym środowisku.
Często spotykamy się z problemem „rozjazdów” na bazie danych pomiędzy poszczególnymi środowiskami, na których jest zainstalowana aplikacja. W przypadku kodu źródłowego utrzymywanie jednej spójnej wersji aplikacji jest stosunkowo proste. Wystarczy użyć jednego z dostępnych systemów kontroli wersji. A co ze strukturą bazy danych, z której korzysta aplikacja? Jak ją wersjonować i utrzymywać jej spójność?
Flyway i Spring Boot – Instalacja zależności i konfiguracja
Jak każda zależność w Spring, tak i Flyway musi zostać zaimportowany do naszego projektu za pośrednictwem np. Maven’a. Dodatkowo musimy stworzyć nowy plugin w naszym pliku pom.xml, który będzie wykorzystywany przez maven’a podczas budowania projektu.
Na początek dodajmy niezbędne zależności. W naszym pokazowym projekcie użyjemy Postgres’a jako bazę danych. Musimy pamiętać, że jeśli chcemy używać bazy danych w naszej aplikacji, to pomocne będzie dodanie też zależności „spring-boot-starter-data-jpa”
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<version>${flyway.version}</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.8</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
Twoje sprawne oko programisty pewnie zobaczyło, że wersja Flyway’a jest ukryta pod placecholderem „${flyway.version}”. Nie musisz definiować tej właściwości samodzielnie w pliku pm.xml. Standardowa konfiguracja zależności Spring Boot’a na Twoim środowisku deweloperskim powinna zawierać definicję wersji Flyway – tak jak na obrazie poniżej.
Wspomniałem wcześniej o implementacji pluginu w pom.xml. Oto on 🙂
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>${flyway.version}</version>
<configuration>
<driver>org.postgresql.Driver</driver>
<url>jdbc:postgresql://localhost:5432/postgres</url>
<user>postgres</user>
<password>my_password</password>
<table>flyway_schema_history</table>
<locations>
<location>classpath:db/migration/</location>
</locations>
</configuration>
</plugin>
Plugin zawiera kilka istotnych informacji. Pierwszą z nich jest definicja połączenia do bazy danych, która będzie wykorzystywana do naszej aplikacji. Standardowo jak dla każdej aplikacji w Spring Boot podajemy tutaj dane o driverze, URL za pomocą którego możemy się połączyć z naszą bazą, nazwa użytkownika oraz hasło.
Flayway do trzymania informacji o wersjach bazy danych wykorzystuję…. właśnie bazę danych 🙂 Oczywiście jest mu potrzebna dedykowana tabela w naszej bazie, która będzie przechowywała informacje o wykonanych migracjach. Jej nazwę można skonfigurować za pomocą opcji „<table>” w pluginie. W projekcie pokazowym jest ona ustawiona na „flyway_schema_history”.
Ostatnim niezbędnym elementem konfiguracji pluginu jest podanie katalogu, w którym będą przetrzymywane skrypty SQL. Możemy podać tu wiele różnych lokalizacji. Dla uproszczenia użyjemy tutaj standardowej lokalizacji „classpath:db/migration/”. Musimy pamiętać, aby utworzyć w naszym projekcie taką strukturę katalogów.
Flyway i Spring Boot – Tworzenie migracji
Kolejnym krokiem, jaki musisz wykonać, jest utworzenie pierwszego pliku migracji. Nazwijmy go V1_0__init_db.sql. Dziwna nazwa? Jest ona podyktowana pewną konwencją nazewniczą. Zawiera ona wersję oraz opis migracji. W naszym przypadku po zbudowaniu aplikacji powinniśmy posiadać bazę danych w wersji 1.0, a nazwa migracji powinna być ustawiona na „init db”. Separatorem tych informacji jest podwujny znak „_”. To, co jest zdefiniowane przed tym separatorem, jest uznawane przez Flyway’a za wersję migracji. Natomiast wszystko za separatorem jest opisem naszej migracji.
Czas napisać Prosty skrypt SQL, który stworzy testową tabelę, która będzie przechowywała podstawowe informacje o użytkownikach aplikacji.
CREATE TABLE USERS (
ID INT NOT NULL,
FIRST_NAME VARCHAR(50) NOT NULL,
LAST_NAME VARCHAR(50) NOT NULL,
EMAIL VARCHAR(50) NOT NULL
);
Zarządzanie migracjami
Do odpalenia naszej migracji wystarczy, że uruchomisz swoją aplikację. Po poprawnym uruchomieniu aplikacji w logach powinniśmy zobaczyć, że Flyway zmigrował bazę danych do wersji 1.0.
W bazie danych widać, że Flyway utworzył dwie tabele:
- FLYWAY_SCHEMA_HISTORY – tabela przechowująca informację o migracjach bazy danych.
- USERS – tabela utworzona podczas migracji. Jej definicja jest zapisana w pliku „V1_0__init_db.sql”
Warto zapoznać się z zawartością tabeli „FLYWAY_SCHEMA_HISTORY”, aby dowiedzieć się, jak Flyway zarządza migracjami. Ta tabela zawiera wiele ciekawych informacji na temat tego, jakie migracje zostały wykonane (lub zakończyły się błędem), datę czas wykonania konkretnej migracji, wymienione wcześniej wersję i opis migracji oraz sumę kontrolną.
Każda migracja posiada swoją sumę kontrolną, więc edycja istniejących plików SQL z migracjami wymaga wyczyszczenia bazy danych przed ponowną migracją. Inaczej Flyway sprawdza sumę kontrolną migracji, nawet jeśli była już wykonana na bazie. Jeśli chcemy zmienić coś w pliku z migracją, to możemy wcześniej wyczyścić bazę danych i uruchomić migrację ponownie. Do czyszczenia bazy danych za pomocą Flyway możemy użyć komendy maven’a
mvn flyway:clean
Oczywiście Flyway udostępnia wiele komend, które pomogą Ci zarządzać wersją bazy danych ręcznie – Zobacz więcej w dokumentacji Flyway’a.
Jeśli potrzebujesz pomocy w skonfigurowaniu Flyway w swoim projekcie, to skontaktuj się z nami!