Liquibase et Maven

Présentation


Liquibase est un système de contrôle de version de base de données, cela concerne principalement la structure et, dans une moindre mesure, le contenu de la base de données. Dans le même temps, la description de la base de données d'une part est assez abstraite et permet l'utilisation de divers SGBD au niveau inférieur, et d'autre part, vous pouvez toujours passer au dialecte SQL d'un SGBD spécifique, ce qui est assez flexible. Liquibase est un projet open source établi et est activement utilisé en dehors de son environnement Java natif et ne nécessite pas de connaissance approfondie de Java pour fonctionner. Un format XML a été historiquement utilisé pour décrire la structure de base et les changements de base, mais maintenant YAML et JSON sont pris en charge en parallèle.


Dans cet article, nous résumerons brièvement l'expérience des générations précédentes et nous concentrerons sur la collaboration avec Liquibase à l'aide de Maven. Nous utiliserons Ubuntu comme système d'exploitation de test.


Autres articles sur Liquibase



Réglage de l'environnement


Il existe plusieurs façons de démarrer Liquibase, cependant, il est plus pratique d'utiliser Maven ou Gradle.


sudo apt install maven mvn -version 

Ici, pom.xml agit comme un Makefile - il contient déjà toutes les dépendances, paramètres et profils nécessaires.


pom.xml
 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.test.db</groupId> <artifactId>db</artifactId> <version>1.0.0</version> <name>db</name> <description>Test Database</description> <packaging>pom</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <slf4j.version>1.7.24</slf4j.version> <logback.version>1.2.3</logback.version> <liquibase.version>3.6.2</liquibase.version> <postgresql.version>42.2.5</postgresql.version> <snakeyaml.version>1.23</snakeyaml.version> </properties> <dependencies> <!--Logging--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>log4j-over-slf4j</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>${logback.version}</version> </dependency> <!--JDBC drivers--> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>${postgresql.version}</version> </dependency> <dependency> <groupId>org.liquibase</groupId> <artifactId>liquibase-core</artifactId> <version>${liquibase.version}</version> </dependency> <dependency> <groupId>org.yaml</groupId> <artifactId>snakeyaml</artifactId> <version>${snakeyaml.version}</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.liquibase</groupId> <artifactId>liquibase-maven-plugin</artifactId> <version>${liquibase.version}</version> <configuration> <propertyFile>${profile.propertyFile}</propertyFile> <changeLogFile>${profile.changeLogFile}</changeLogFile> <dataDir>${profile.dataDir}</dataDir> <!-- log --> <verbose>${profile.verbose}</verbose> <logging>${profile.logging}</logging> <promptOnNonLocalDatabase>false</promptOnNonLocalDatabase> </configuration> </plugin> </plugins> </build> <profiles> <!-- Development settings, -Denv=dev --> <profile> <id>dev</id> <activation> <property> <name>env</name> <value>dev</value> </property> </activation> <properties> <profile.propertyFile>dev/liquibase.properties</profile.propertyFile> <profile.changeLogFile>dev/master.xml</profile.changeLogFile> <profile.dataDir>dev/data</profile.dataDir> <profile.verbose>true</profile.verbose> <profile.logging>debug</profile.logging> </properties> </profile> <!-- Production settings, -Denv=prod --> <profile> <id>prod</id> <activation> <property> <name>env</name> <value>prod</value> </property> </activation> <properties> <profile.propertyFile>prod/liquibase.properties</profile.propertyFile> <profile.changeLogFile>prod/master.xml</profile.changeLogFile> <profile.dataDir>prod/data</profile.dataDir> <profile.verbose>false</profile.verbose> <profile.logging>info</profile.logging> </properties> </profile> </profiles> </project> 

Nous lançons la mise à jour


Après avoir fait pom.xml, nous pouvons commencer à mettre à jour la base de données - la commande liquibase: update.


Pour cela, nous avons besoin de:


  • Fichier liquibase.properties avec les paramètres de connexion à la base de données (nom d'utilisateur / mot de passe et éventuellement d'autres paramètres)
  • fichier xml avec modifications de base
  • script de démarrage de mise à jour de la base de données sh

Fichier de paramètres de connexion à la base de données


liquibase.properties


 username=test password=test referenceUsername=test #     #url=jdbc:postgresql://dev/test #referenceUrl=jdbc:postgresql://dev/test_reference 

Fichier de modifications de base


Le concept principal de la base de données est ce que l'on appelle les changements de base (changesets). Ils peuvent inclure à la fois des changements structurels et des changements de données. Liquibase utilise les tables databasechangelog et databasechangeloglock pour surveiller les modifications appliquées.


 <?xml version="1.1" encoding="UTF-8" standalone="no"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> <changeSet context="legacy" author="author (generated)" id="1"> <createTable tableName="test"> <column autoIncrement="true" name="id" type="SERIAL"> <constraints nullable="false"/> </column> <column name="user_name" type="VARCHAR(255)"/> <column name="preferences" type="TEXT"/> </createTable> </changeSet> </databaseChangeLog> 

Script de démarrage de la mise à jour de la base de données


Ici liquibase: la mise à jour est exécutée pour le profil dev et la base de liquibase.url, qui est spécifié au format JDBC standard. Après la mise à jour, la table indiquée dans changeSet et deux tables de services databasechangelog et databasechangeloglock apparaissent dans la base de données .


 #!/usr/bin/env bash mvn liquibase:update\ -Denv=dev\ -Dliquibase.url="jdbc:postgresql://dev/test?prepareThreshold=0&stringtype=unspecified" 

Génération SQL sans mise à jour de la base de données


Parfois, avant de commencer les modifications, vous devez regarder le contenu des requêtes générées. Les commandes liquibase: updateSQL et liquibase: rollbackSQL sont prévues à cet effet.


 #!/usr/bin/env bash mvn liquibase:updateSQL\ -Denv=dev\ -Dliquibase.url="jdbc:postgresql://dev/test?prepareThreshold=0&stringtype=unspecified" > /tmp/script.sql 

En savoir plus sur changeSet


Les modifications peuvent être dans différents formats, y compris SQL standard ou dans un fichier séparé.


Chaque modification peut inclure une section de restauration vous permettant d' annuler les modifications avec la commande liquibase: rollback . De plus, vous pouvez utiliser tagDatabase pour marquer les modifications, par exemple, pour y revenir plus facilement.


Format normal


 <changeSet context="legacy" author="author (generated)" id="1"> <createTable tableName="test"> <column autoIncrement="true" name="id" type="SERIAL"> <constraints primaryKey="true" primaryKeyName="test_pkey"/> </column> <column name="c1" type="VARCHAR(255)"/> <column name="c2" type="INTEGER"/> <column name="c3" type="SMALLINT"/> <column name="c4" type="VARCHAR(255)"/> <column name="c5" type="TEXT"/> <column name="c6" type="VARCHAR(255)"/> </createTable> </changeSet> 

Embedded SQL


 <changeSet context="legacy" author="author" id="1-domain-some-domain"> <sql> CREATE DOMAIN public.some_domain AS bigint; ALTER DOMAIN public.some_domain OWNER TO test; </sql> <rollback> DROP DOMAIN public.some_domain; </rollback> </changeSet> 

Fichier SQL


 <changeSet context="legacy" author="author" id="1-user"> <sqlFile dbms="postgresql" path="sql/some.sql" relativeToChangelogFile="true" /> <rollback> delete from "some"; </rollback> </changeSet> 

Balises


 <changeSet context="legacy" author="author" id="1-initial-changeset"> <tagDatabase tag="initial"/> </changeSet> 

Contextes de lancement


Pour une gestion plus pratique de diverses configurations, par exemple, développement / production, des contextes peuvent être utilisés. Le contexte est spécifié dans l'attribut changeSet du contexte, puis lancé par Maven avec le paramètre -Dcontexts.


Changer avec le contexte


 <changeSet context="legacy" author="author" id="1-initial-changeset"> <tagDatabase tag="initial"/> </changeSet> 

Déclenchement des changements de contexte


 #!/usr/bin/env bash mvn liquibase:update\ -Denv=dev\ -Dliquibase.url="jdbc:postgresql://dev/test?prepareThreshold=0&stringtype=unspecified"\ -Dliquibase.contexts=non-legacy 

Annuler les modifications


L'opération est l'opposé de la mise à jour, dans la plupart des cas, elle est prise en charge automatiquement. Pour d'autres, la tâche est possible via la section de restauration. Il est lancé par la commande liquibase: rollback.


Changer avec restauration


 <changeSet context="legacy" author="author" id="1-domain-some-domain"> <sql> CREATE DOMAIN public.some_domain AS bigint; ALTER DOMAIN public.some_domain OWNER TO test; </sql> <rollback> DROP DOMAIN public.some_domain; </rollback> </changeSet> 

Lancer la restauration


 #!/usr/bin/env bash mvn liquibase:update\ -Denv=dev\ -Dliquibase.url="jdbc:postgresql://dev/test?prepareThreshold=0&stringtype=unspecified"\ -Dliquibase.contexts=non-legacy 

Comparaison


En cours de développement, il est pratique d'utiliser pour comparer deux bases de données existantes pour les modifications apportées. Dans les paramètres (ou paramètres de lancement), vous devrez ajouter un lien vers la base de données de référence et les données pour y accéder.


liquibase.properties


 referenceUsername=test referenceUrl=jdbc:postgresql://dev/test_reference 

Comparaison de circuits


Comparaison des schémas url et referenceUrl.


 #!/usr/bin/env bash mvn liquibase:diff\ -Denv=dev\ -Dliquibase.referenceUrl="jdbc:postgresql://dev/test?prepareThreshold=0"\ -Dliquibase.url="jdbc:postgresql://dev/test_reference?prepareThreshold=0"\ -Dliquibase.diffChangeLogFile=dev/diff.xml 

Enregistrement du schéma


Il peut également être utile d'enregistrer le schéma de base de données actuel, avec ou sans données. Il faut garder à l'esprit que Liquibase enregistre un schéma qui ne correspond pas entièrement à l'original, par exemple, les domaines utilisés ou l'héritage devront être ajoutés séparément (voir Restrictions).


Sauvegarder un schéma sans prendre en compte les données


Enregistrement du schéma d'une base de données existante


 #!/usr/bin/env bash mvn liquibase:generateChangeLog\ -Denv=dev\ -Dliquibase.url="jdbc:postgresql://dev/test_reference?prepareThreshold=0"\ -Dliquibase.outputChangeLogFile=dev/changelog.xml 

Enregistrement d'un schéma avec des données


Enregistrement du schéma d'une base de données existante avec des données.


 #!/usr/bin/env bash mvn liquibase:generateChangeLog\ -Denv=dev\ -Dliquibase.url="jdbc:postgresql://dev/test_reference?prepareThreshold=0"\ -Dliquibase.outputChangeLogFile=dev/changelog.xml 

Limitations et problèmes


Travailler avec des données binaires dans la base de données


Il y a certains problèmes avec le téléchargement, la comparaison et l'utilisation de données binaires, en particulier un problème avec la génération de changements.



Héritage et colonnes communes



Code source



Solutions alternatives


Flyway


Avec Liquibase est populaire dans la communauté Java - http://flywaydb.org/documentation


Sqqitch


Équivalent Perl - http://sqitch.org


Fluentmigrator


Analogique pour .Net - https://github.com/schambers/fluentmigrator


Dbgeni


Analogue pour Ruby - http://dbgeni.appsintheopen.com/manual.html


Les applications


Structure du projet


 pom.xml - maven makefile dev liquibase.properties - login/password etc master.xml - changesets 

Comment ajouter une base de données à un projet existant



Fonctionnement des changements de base



En savoir plus sur le changement de format



En savoir plus sur la mise à jour



Plus sur la génération de changement



En savoir plus sur le SQL personnalisé



Traitement des types de données spécifiques à la base de données


 <createTable tableName="t_name"> ... <column name="doubleArray" type="DOUBLE_ARRAY"/> ... </createTable> <modifySql dbms="postgresql"> <replace replace="DOUBLE_ARRAY" with="double precision[][]"/> </modifySql> 

Autre


Source: https://habr.com/ru/post/fr436994/


All Articles