Outils pour utilisateurs

Outils du site


techniques:liquibase

Présentation

Liquibase est un gestionnaire de mise à jour de base de donnée Il permet la mise à jour du schéma et des données. Le principe consiste à créer pour chaque évolution un “changelog” (c'est un fichier xml) et de le référencer dans le fichier de gestion des révisions, en général nommé master.xml.

Ce changelog ne sera joué qu'une seule fois (si il réussit)

Il faut tout de suite rentrer un peu plus dans les détails :

 master.xml contient des fichier changelogs
    changelog, qui contient des changeset
        changeset id=XXXXX, qui contient
            changeset entries qui sont fait les actions de modifications de la base

Pour fonctionner, liquibase va créer 2 tables supplémentaire dans la base de données :

Table databasechangelog

<sxh java>

La description est parlante, à part le md5sum ; il est créé pour chaque changelog, lors de son exécution Il s'agit d'une empreinte générée à partir des éléments du fichier xml changelog touchant à la base de donnée (i.e le contenu des changeset entry) ; les autres éléments sont ignorés du calcul. Cela permet de l'authentifier.

Pendant son exécution, liquibase recalcule l'empreinte md5 tous les changelogs déjà exécutés et s'assure qu'il correspondent bien à celui historisé en base dans la table datachangelog. Cela démontre qu'aucun changesetlog n'a été modifié. Si il en trouve un, alors il plantera en fournissant la stacktrace ci-dessous.

</sxh>

<sxh java>

   1 change sets check sum
        classpath:config/liquibase/changelog/00000000000000_initial_schema.xml::00000000000001::jhipster is now: 7:c544e5ee3ae4aae8b6a8d0b554712f3a

liquibase.exception.ValidationFailedException: Validation Failed:

   1 change sets check sum
        classpath:config/liquibase/changelog/00000000000000_initial_schema.xml::00000000000001::jhipster is now: 7:c544e5ee3ae4aae8b6a8d0b554712f3a
at liquibase.changelog.DatabaseChangeLog.validate(DatabaseChangeLog.java:215)
at liquibase.Liquibase.update(Liquibase.java:208)
at liquibase.Liquibase.update(Liquibase.java:192)
at liquibase.integration.spring.SpringLiquibase.performUpdate(SpringLiquibase.java:434)
      ...

</sxh>

Si aucun changelog exécuté n'a été modifié, et qu'un nouveau changelog doit être exécuté, alors liquibase tentera d'exécuter le nouveau changelog.

Il ne l'inscrira en base que si l'exécution complète n'a pas posée de problèmes.

Table databasechangeloglock

Elle empêche certainement que 2 liquibase tournent en même temps sur la même base.

Le fichier master.xml

<sxh xml>

<?xml version=“1.0” encoding=“utf-8”?> <databaseChangeLog

  xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.4.xsd">
  <include file="classpath:config/liquibase/changelog/00000000000000_initial_schema.xml" relativeToChangelogFile="false"/>
  <include file="classpath:config/liquibase/changelog/20161201124308_added_entity_Category.xml" relativeToChangelogFile="false"/>
  <include file="classpath:config/liquibase/changelog/20161201124309_added_entity_CategorySet.xml" relativeToChangelogFile="false"/>

/> </sxh>

A noter que relativeToChangelogFile ne sert qu'à préciser si le chemin indiqué pour ce changelog est relatif au dossier de master.xml

Mise en place

Dépendances

<sxh xml>

  <dependency>
      <groupId>org.liquibase</groupId>
      <artifactId>liquibase-core</artifactId>
      <version>3.4.2</version>
  </dependency>
  <dependency>
    <groupId>com.mattbertolini</groupId>
    <artifactId>liquibase-slf4j</artifactId>
    <version>2.0.0</version>
    <scope>compile</scope>

</dependency> </sxh>

Plugins maven

<sxh xml>

  <plugin>
    <groupId>org.liquibase</groupId>
    <artifactId>liquibase-maven-plugin</artifactId>
    <version>3.4.2</version>
    <dependencies>
      <dependency>
        <groupId>org.javassist</groupId>
        <artifactId>javassist</artifactId>
        <version>3.18.2-GA</version>
        <scope>compile</scope>
      </dependency>
      <dependency>
        <groupId>org.liquibase.ext</groupId>
        <artifactId>liquibase-hibernate4</artifactId>
        <version>3.5</version>
        <scope>compile</scope>
      </dependency>
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
        <version>1.4.1.RELEASE</version>
        <scope>compile</scope>
      </dependency>
    </dependencies>
    <configuration>
      <changeLogFile>src/main/resources/config/liquibase/master.xml</changeLogFile>
      <diffChangeLogFile>src/main/resources/config/liquibase/changelog/20180105220221_changelog.xml</diffChangeLogFile>
      <driver>com.mysql.jdbc.Driver</driver>
      <url>jdbc:mysql://localhost:3306/testify_jhi</url>
      <defaultSchemaName>testify_jhi</defaultSchemaName>
      <username>root</username>
      <password>root</password>
      <referenceUrl>hibernate:spring:fr.softeam.testify.domain?dialect=org.hibernate.dialect.MySQL5InnoDBDialect&amp;hibernate.ejb.naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringNamingStrategy</referenceUrl>
      <verbose>true</verbose>
      <logging>debug</logging>
    </configuration>

</plugin> </sxh>

Lancer liquibase sur son projet

Lancer l'application si liquibase est activé au démarrage de l'application

Il est aussi possible de lancer liquibase au lancement de l'application web.

Cela se fait en utilisant la classe SpringLiquibase par exemple. Pour plus d'info, voir l'article projet testify

Lancer liquibase avec maven

E1 : Trouver le plugin liquibase dans le pom.xml du projet testify_jhi :

    <plugin>
      <groupId>org.liquibase</groupId>
      <artifactId>liquibase-maven-plugin</artifactId>
      <version>3.4.2</version>

Ajouter au plugin liquibase les exécutions suivantes : <sxh xml>

      <executions>
        <execution>
          <phase>process-resources</phase>
          <goals>
            <goal>update</goal>
          </goals>
          <configuration>
            <changeLogFile>src/main/resources/config/liquibase/master.xml</changeLogFile>
            <diffChangeLogFile>src/main/resources/config/liquibase/changelog/20180117163143_changelog.xml</diffChangeLogFile>
            <driver>com.mysql.jdbc.Driver</driver>
            <url>jdbc:mysql://localhost:3306/testify_jhi</url>
            <defaultSchemaName>testify_jhi</defaultSchemaName>
            <username>root</username>
            <password>root</password>
            <referenceUrl>hibernate:spring:fr.softeam.testify.domain?dialect=org.hibernate.dialect.MySQL5InnoDBDialect&amp;hibernate.ejb.naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringNamingStrategy</referenceUrl>
            <verbose>true</verbose>
            <logging>debug</logging>
          </configuration>
        </execution>
      </executions>

</sxh>

E2 : Sous eclipse, indiquer Workspace : ${workspace_loc:/testify_jhi}

Goals : org.liquibase:liquibase-maven-plugin:update

Lancer liquibase en ligne de commande

Prerequis :

  1. connaitre le driver mysql ou oracle à utiliser, l'url de la base de donnée, compte et mot de passe
  2. connaitre l'emplacement de son fichier master.xml, et le dossier où sont placés les changelogs
  3. connaitre le jar core de liquibase, contenant un manifest avec une MainClass pour la commandline
  4. créer un fichier liquibase.properties contenant les infos précédentes

Voici mon fichier <sxh java>

driver: com.mysql.jdbc.Driver
classpath: C:/Users/xavier/.m2/repository/mysql/mysql-connector-java/5.1.39/mysql-connector-java-5.1.39.jar;D:/Programmation/java/Projet/testify_jhi/src/main/resources
url: jdbc:mysql://localhost:3306/testify_jhi
username: root
password: root 

</sxh>

Exécuter :

 java -jar <mavenFilePathTo>/liquibase-core-3.4.2.jar --changeLogFile="./config/liquibase/master.xml" validate

Il est aussi possible de ne pas se servir du fichier liquibase.properties et de passer tous les paramètres :

 java -jar <mavenFilePathTo>/liquibase-core-3.4.2.jar \
    --driver=com.mysql.jdbc.Driver \
    --url=jdbc:mysql://localhost:3306/testify_jhi \
    --username=root \
    --password=root \
    --classpath: <PathTo>/mysql-connector-java-5.1.39.jar;D:/Programmation/java/Projet/testify_jhi/src/main/resources \
    --changeLogFile="./config/liquibase/master.xml" \
    update

Forcer à recalculer un checksum

Manuellement, en SQL

E1 : Faire ses modif dans le changetset d'id <idChangeset> le fichier xml changelog, et enregistrer le fichier

E2 : Relancer liquibase (validate ou update) Normalement, il devrait planter en indiquant que le fichier xml a été modifié et en fournissant le nouveau MD5 <newMD5> du changeset <idChangeset> Dans ce cas là, liquibase s'arrête et ne fera aucune update.

E3 :

 update databasechangelog set md5sum=<newMD5> where id=<idChangeset>; commit;

E4 : Relancer liquibase ; cette fois-ci tout devrait être bon

Via la ligne de commande

 java -jar <mavenFilePathTo>/liquibase-core-3.4.2.jar --changeLogFile="./config/liquibase/master.xml" clearCheckSums

Normalement, à la prochaine exécution de liquibase, tous les md5 sont regénérés.

Attention : clearCheckSums vide les MD5 de *TOUS* les changelogs

Notion de tag et de retour arrière

Il est possible de tagguer un état de la base. Cela permet de faire des retour arrière (“rollback”) pour remettre la base de donnée dans l'état où elle était à un tag donné.

Ajout d'un changelog

Il suffit d'ajouter une ligne dans le fichier master.xml :

 <include file="<newChangelogXmlFilePath>" relativeToChangelogFile="false"/>

De créer le fichier xml <newChangelogXmlFilePath> qui contient les instructions de modifications en base à exécuter. Ces instructions sont donc des tags xml, le site de liquibase fournit la syntaxe.

Suite à cela, en relancant liquibase par l'application ou en standalone, liquibase va identifier ce nouveau changelog, l'inscrire dans la table databasechangelog et tenter de l'exécuter.

Remarque importante : Le changelog ne sera inséré en base que si liquibase a réussi à complètement le jouer. =⇒ Il commit donc les changements en base par exécution de changelog entier.

=⇒ Cela permet de travailler à le faire passer en toute sécurité.

techniques/liquibase.txt · Dernière modification: 2018/01/18 09:50 (modification externe)