Databasemigraties met Flyway

1. Inleiding

Dit artikel beschrijft de belangrijkste concepten van Flyway en hoe we dit raamwerk kunnen gebruiken om continu het databaseschema van onze applicatie betrouwbaar en gemakkelijk te hermodelleren. Aan het einde zullen we een voorbeeld geven van het beheren van een in-memory H2-database met behulp van een Maven Flyway-plug-in.

Flyway werkt een database bij van de ene versie naar de andere door middel van migraties. We kunnen migraties schrijven in SQL met databasespecifieke syntaxis of in Java voor geavanceerde databasetransformaties.

Migraties kunnen zowel in versiebeheer als herhaalbaar zijn. De eerste heeft een unieke versie en wordt precies één keer aangebracht. De laatste heeft geen versie. In plaats daarvan worden ze (opnieuw) toegepast elke keer dat hun checksum verandert.

Binnen een enkele migratierun worden herhaalbare migraties altijd als laatste toegepast, nadat migraties in afwachting van versiebeheer zijn uitgevoerd. Herhaalbare migraties worden toegepast in de volgorde van hun beschrijving. Bij een enkele migratie worden alle instructies uitgevoerd binnen een enkele databasetransactie.

In dit artikel richten we ons voornamelijk op hoe we de Maven-plug-in kunnen gebruiken om databasemigraties uit te voeren.

2. Flyway Maven-plug-in

Om een ​​Flyway Maven-plug-in te installeren, voegen we de volgende plug-in-definitie toe aan onze pom.xml:

 org.flywaydb flyway-maven-plugin 4.0.3 

We kunnen de nieuwste versie van de plug-in bekijken die beschikbaar is op Maven Central.

Deze Maven-plug-in kan op vier verschillende manieren worden geconfigureerd. Raadpleeg de documentatie voor een lijst met alle configureerbare eigenschappen.

2.1. Plug-in configuratie

We kunnen de plug-in rechtstreeks configureren via het tag in de plugin-definitie van onze pom.xml:

 org.flywaydb flyway-maven-plugin 4.0.3 databaseGebruikersdatabaseWachtwoordschemaNaam ... 

2.2. Maven-eigenschappen

We kunnen de plug-in ook configureren door configureerbare eigenschappen op te geven als Maven eigendommen in onze pom:

 ... databaseGebruikersdatabasePassword schemaNaam ... ... 

2.3. Extern configuratiebestand

We kunnen ook de configuratie van de plug-in in een afzonderlijk .eigendommen het dossier:

flyway.user = databaseUser flyway.password = databasePassword flyway.schemas = schemaName ...

De standaardnaam van het configuratiebestand is flyway.properties en het zou in dezelfde map moeten staan ​​als het pom.xml het dossier. Codering wordt gespecificeerd door flyway.encoding (Standaard is UTF-8).

Als u een andere naam gebruikt (bijv customConfig.properties) als het configuratiebestand, dan moet het expliciet worden gespecificeerd bij het aanroepen van het Maven-commando:

$ mvn -Dflyway.configFile = customConfig.properties

2.4. Systeem eigenschappen

Ten slotte kunnen alle configuratie-eigenschappen ook worden gespecificeerd als systeemeigenschappen bij het aanroepen van Maven op de opdrachtregel:

$ mvn -Dflyway.user = databaseUser -Dflyway.password = databasePassword -Dflyway.schemas = schemaName

Hieronder volgt een volgorde van prioriteit wanneer een configuratie op meer dan één manier is gespecificeerd:

  1. Systeem eigenschappen
  2. Extern configuratiebestand
  3. Maven eigenschappen
  4. Plug-in configuratie

3. Voorbeeldmigratie

In deze sectie doorlopen we de vereiste stappen om een ​​databaseschema te migreren naar een in-memory H2-database met behulp van de Maven-plug-in. We gebruiken een extern bestand om Flyway te configureren.

3.1. Werk POM bij

Laten we eerst H2 als afhankelijkheid toevoegen:

 com.h2database h2 1.4.196 

We kunnen nogmaals de nieuwste versie van de driver bekijken die beschikbaar is op Maven Central. We zouden ook de Flyway-plug-in toevoegen, zoals eerder uitgelegd.

3.2. Configureer Flyway met extern bestand

Vervolgens maken we myFlywayConfig.properties in $ PROJECT_ROOT met de volgende inhoud:

flyway.user = databaseUser flyway.password = databasePassword flyway.schemas = app-db flyway.url = jdbc: h2: mem: DATABASE flyway.locations = bestandssysteem: db / migratie

De bovenstaande configuratie geeft aan dat onze migratiescripts zich in het db / migratie directory. Het maakt verbinding met een H2-instantie in het geheugen met behulp van databaseUser en databasePassword.

Het databaseschema van de applicatie is app-db.

Natuurlijk vervangen we flyway.user, flyway.wachtwoord, en flyway.url met onze eigen database-gebruikersnaam, database-wachtwoord en database-URL op de juiste manier.

3.3. Definieer de eerste migratie

Flyway houdt zich aan de volgende naamgevingsconventie voor migratiescripts:

__. sql

Waar:

  • - Standaard voorvoegsel is V., die kan worden geconfigureerd in het bovenstaande configuratiebestand met behulp van de flyway.sqlMigrationPrefix eigendom.
  • - Versienummer van de migratie. Grote en secundaire versies kunnen worden gescheiden door een laag streepje. De migratieversie moet altijd beginnen met 1.
  • - Tekstuele beschrijving van de migratie. De beschrijving moet worden gescheiden van de versienummers met een dubbele onderstreping.

Voorbeeld: V1_1_0__my_first_migration.sql

Laten we dus een map maken db / migratie in $ PROJECT_ROOT met een migratiescript genaamd V1_0__create_employee_schema.sql met SQL-instructies om de werknemerstabel te maken:

TABEL MAKEN INDIEN NIET BESTAAT `medewerker` (` id` int NOT NULL AUTO_INCREMENT PRIMAIRE SLEUTEL, `naam` varchar (20),` e-mail` varchar (50), `datum_geboortedatum`) ENGINE = InnoDB STANDAARD CHARSET = UTF8;

3.4. Voer migraties uit

Vervolgens roepen we het volgende Maven-commando op van $ PROJECT_ROOT om databasemigraties uit te voeren:

$ mvn clean flyway: migrate -Dflyway.configFile = myFlywayConfig.properties

Dit zou moeten resulteren in onze eerste succesvolle migratie.

Het databaseschema moet nu als volgt worden weergegeven:

medewerker: + ---- + ------ + ------- + --------------- + | id | naam | e-mail | geboortedatum | + ---- + ------ + ------- + --------------- +

We kunnen de definitie- en uitvoeringsstappen herhalen om meer migraties uit te voeren.

3.5. Definieer en voer een tweede migratie uit

Laten we eens kijken hoe een tweede migratie eruitziet door een tweede migratiebestand met naam te maken V2_0_create_department_schema.sql met de volgende twee vragen:

TABEL MAKEN INDIEN NIET BESTAAT `department` (` id` int NOT NULL AUTO_INCREMENT PRIMARY KEY, `name` varchar (20)) ENGINE = InnoDB DEFAULT CHARSET = UTF8; WIJZIGINGSTABEL `medewerker` TOEVOEGEN` afd_id` int NA `e-mail`;

We voeren een vergelijkbare migratie uit zoals we de eerste keer deden.

En nu is ons databaseschema gewijzigd om er een nieuwe kolom aan toe te voegen werknemer en een nieuwe tafel:

medewerker: + ---- + ------ + ------- + --------- + --------------- + | id | naam | e-mail | afd_id | geboortedatum | + ---- + ------ + ------- + --------- + --------------- +
afdeling: + ---- + ------ + | id | naam | + ---- + ------ +

We kunnen nu verifiëren dat beide migraties inderdaad succesvol waren door het volgende Maven-commando aan te roepen:

$ mvn flyway: info -Dflyway.configFile = myFlywayConfig.properties

4. Flyway uitschakelen in Spring Boot

Soms is dat nodig Schakel Flyway-migraties onder bepaalde omstandigheden uit.

Het is bijvoorbeeld gebruikelijk om tijdens tests een databaseschema te genereren op basis van de entiteiten. In een dergelijke situatie kunnen we Flyway uitschakelen onder de test profiel.

Laten we kijken hoe gemakkelijk het is in Spring Boot.

4.1. Spring Boot 1.x

Het enige wat we hoeven te doen is stel de flyway. ingeschakeld eigendom in ons application-test.properties het dossier:

flyway.enabled = false

4.2. Spring Boot 2.x

In de recentere versies van Spring Boot, deze eigenschap is gewijzigd in spring.flyway.enabled:

spring.flyway.enabled = false

4.3 Leeg FlywayMigrationStrategy

Als we dat maar willen schakel automatische Flyway-migratie uit bij het opstarten, maar u kunt de migratie nog steeds handmatig activeren, dan is het gebruik van de hierboven beschreven eigenschappen geen goede keuze.

Dat komt omdat Spring Boot in een dergelijke situatie het Flyway boon meer. Daarom zouden we het zelf moeten regelen, wat niet erg handig is.

Dus als dit onze use case is, kunnen we Flyway ingeschakeld laten en een leeg FlywayMigrationStrategy:

@Configuration openbare klasse EmptyMigrationStrategyConfig {@Bean openbare FlywayMigrationStrategy flywayMigrationStrategy () {return flyway -> {// niets doen}; }}

Dit zal effectief schakel Flyway-migratie uit bij het opstarten van de applicatie.

Maar we kunnen de migratie nog steeds handmatig activeren:

@RunWith (SpringRunner.class) @SpringBootTest openbare klasse ManualFlywayMigrationIntegrationTest {@Autowired privé Flyway flyway; @Test openbare ongeldige skipAutomaticAndTriggerManualFlywayMigration () {flyway.migrate (); }}

5. Hoe Flyway werkt

Om bij te houden welke migraties al zijn toegepast, wanneer en door wie, voegt het een speciale boekhoudingstabel toe aan uw schema. Deze metadatatabel houdt ook migratiecontrolesommen bij en of de migraties al dan niet succesvol waren.

Het framework voert de volgende stappen uit om tegemoet te komen aan evoluerende databaseschema's:

  1. Het controleert een databaseschema om de metadatatabel (SCHEMA_VERSION standaard). Als de metadatatabel niet bestaat, wordt er een gemaakt
  2. Het scant een toepassingsklassenpad op beschikbare migraties
  3. Het vergelijkt migraties met de metadatatabel. Als een versienummer lager of gelijk is aan een versie die als actueel is gemarkeerd, wordt dit genegeerd
  4. Het markeert alle resterende migraties als in afwachting van migraties. Deze zijn gesorteerd op versienummer en worden op volgorde uitgevoerd
  5. Bij elke migratie wordt de metagegevenstabel dienovereenkomstig bijgewerkt

6. Commando's

Flyway ondersteunt de volgende basisopdrachten om databasemigraties te beheren.

  • Info: Drukt de huidige status / versie van een databaseschema af. Het drukt af welke migraties in behandeling zijn, welke migraties zijn toegepast, wat de status is van toegepaste migraties en wanneer deze zijn toegepast.
  • Migreren: Migreert een databaseschema naar de huidige versie. Het scant het klassenpad op beschikbare migraties en past hangende migraties toe.
  • Basislijn: Baselines een bestaande database, met uitzondering van alle migraties, inclusief baselineVersion. Baseline helpt bij het starten met Flyway in een bestaande database. Nieuwere migraties kunnen dan normaal worden toegepast.
  • Valideer: Valideert het huidige databaseschema ten opzichte van beschikbare migraties.
  • Reparatie: Herstelt metadatatabel.
  • Schoon: Verwijdert alle objecten in een geconfigureerd schema. Alle database-objecten worden verwijderd. U mag natuurlijk nooit clean gebruiken voor een productiedatabase.

7. Conclusie

In dit artikel hebben we laten zien hoe Flyway werkt en hoe we dit framework kunnen gebruiken om onze applicatiedatabase betrouwbaar te hermodelleren.

De code bij dit artikel is beschikbaar op GitHub.