[Из песочницы] Liqubase и Maven

habr.png

Введение

Liquibase представляет из себя систему управления версиями базы данных, в основном это касается структуры и в меньшей степени содержимого базы. При этом описание базы с одной стороны достаточно абстрактно и позволяет использовать на нижнем уровне различные СУБД, и с другой стороны всегда можно перейти на SQL-диалект конкретной СУБД, что достаточно гибко. Liquibase является устоявшимся проектом с открытым исходным кодом и активно используется за пределами своей родной Java среды и не требует глубоких знаний Java для работы. В качестве описания структуры базы и изменений базы исторически использовался XML формат, однако сейчас параллельно поддерживается YAML и JSON.

В данной статье мы немного обобщим опыт предыдущих поколений и сосредоточимся на работе с Liquibase с использованием Maven. В качестве тестовой операционной системы будем использовать Ubuntu.


Другие статьи о Liquibase


Настройка окружения

Запускать Liquibase можно несколькими способами, однако наиболее удобно использовать Maven — по сути Java Make.

sudo apt install maven
mvn -version

В качестве Makefile здесь выступает pom.xml — он уже содержит все необходимые зависимости, настройки и профили.


pom.xml


    4.0.0
    com.test.db
    db
    1.0.0
    db
    Test Database
    pom
    
        UTF-8
        UTF-8
        1.7.24
        1.2.3
        3.6.2
        42.2.5
        1.23
    
    
        
        
            org.slf4j
            slf4j-api
            ${slf4j.version}
        
        
            org.slf4j
            log4j-over-slf4j
            ${slf4j.version}
        
        
            org.slf4j
            jcl-over-slf4j
            ${slf4j.version}
        
        
            ch.qos.logback
            logback-classic
            ${logback.version}
        

        
        
            org.postgresql
            postgresql
            ${postgresql.version}
        
        
            org.liquibase
            liquibase-core
            ${liquibase.version}
        
        
            org.yaml
            snakeyaml
            ${snakeyaml.version}
        
    
    
        
            
                org.liquibase
                liquibase-maven-plugin
                ${liquibase.version}
                
                    ${profile.propertyFile}
                    ${profile.changeLogFile}
                    ${profile.dataDir}
                    
                    ${profile.verbose}
                    ${profile.logging}
                    false
                
            
        
    

    
      
      
        dev
        
          
            env
            dev
          
        
        
          dev/liquibase.properties
          dev/master.xml
          dev/data
          true
          debug
        
      
      
      
        prod
        
          
            env
            prod
          
        
        
          prod/liquibase.properties
          prod/master.xml
          prod/data
          false
          info
        
      
    


Запускаем обновление

После того как мы сделали pom.xml можно запускать обновление базы — команда liquibase: update.

Для этого нам потребуются:


  • liquibase.properties файл с настройками соединения к базе (логин/пароль и возможно другие параметры)
  • xml файл с изменениями базы
  • sh скрипт запуска обновления базы


Файл с настройками соединения к базе

liquibase.properties

username=test
password=test
referenceUsername=test
#можно задавать и другие параметры
#url=jdbc:postgresql://dev/test
#referenceUrl=jdbc:postgresql://dev/test_reference


Файл с изменениями базы

Основным понятием liquibase являются так называемые изменения базы (changesets). Они могут включать в себя как изменения структуры так и изменение данных. Для контроля примененных изменений liquibase использует таблицы databasechangelog и databasechangeloglock.




    
        
            
                
            
            
            
        
    


Скрипт запуска обновления базы

Здесь выполняется liquibase: update для профиля dev и базы из liquibase.url, которая указана в стандартном JDBC формате. После обновления в базе появляется указанная в changeSet таблица и две служебные таблицы databasechangelog и databasechangeloglock.

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


Генерация SQL без обновления базы

Иногда перед запуском изменений требуется посмотреть содержимое создаваемых запросов. Для этого предназначены команды liquibase: updateSQL и liquibase: rollbackSQL.

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


Подробнее о changeSet

Изменения могут быть в разных форматах, в том числе обычный sql или он же в отдельном файле.

Каждое изменение может включать секцие rollback позволяющую откатывать изменения командой liqubase: rollback. Кроме того для маркировки изменений, например для более удобного отката туда, можно использовать tagDatabase.


Обычный формат


    
        
            
        
        
        
        
        
        
        
    


Встроенный SQL


    
        CREATE DOMAIN public.some_domain AS bigint;
        ALTER DOMAIN public.some_domain OWNER TO test;
    
    
        DROP DOMAIN public.some_domain;
    


Файл SQL


     
      delete from "some"; 


Тэги


    


Контексты запуска

Для более удобного управления различными конфигурациями, например development/production можно использовать контексты. Контекст указывается в changeSet аттрибуте context и затем запускается Maven параметром -Dcontexts.


Изменение с контекстом


    


Запуск изменений по контексту

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


Откат изменений

Операция обратная обновлению, в большинстве случаев поддерживается автоматически. Для прочих возможно задание через секцию rollback. Запускается командой liquibase: rollback.


Изменение с откатом


    
        CREATE DOMAIN public.some_domain AS bigint;
        ALTER DOMAIN public.some_domain OWNER TO test;
    
    
        DROP DOMAIN public.some_domain;
    


Запуск отката

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


Сравнение

В разработке удобно использовать для сравнения двух существующих баз на предмет внесённых изменений. В настройки (или параметры запуска) потребуется добавить ссылку на референсную базу и данные для доступа к ней.

liquibase.properties

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


Сравнение схем

Сравнение схем url и 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


Сохранение схемы

Также бывает полезно сохранить текущую схему базы, с данными или без.


Сохранение схемы без учёта данных

Сохранение схемы существующей базы.

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


Сохранение схемы с данными

Сохранение схемы существующей базы с данными.

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


Ограничения и проблемы


Работа с бинарными данными в базе

Существуют отпределенные проблемы с выгрузкой, сравнением и применением бинарных данных, в частности проблема с генерацией изменений.


Исходный код


Альтернативные решения


Flyway

Наряду с Liquibase пользуется популярностью в Java сообществе — http://flywaydb.org/documentation


Sqitch

Аналог на Perl — http://sqitch.org


FluentMigrator

Аналог для .Net — https://github.com/schambers/fluentmigrator


DBGeni

Аналог для Ruby — http://dbgeni.appsintheopen.com/manual.html


Приложения


Структура проекта

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


Как добавить liquibase в существующий проект


Как работают изменения базы


Больше о формате изменений


Больше про update


Больше о генерации изменений


Больше о кастомном SQL


Обработка типов данных специфичних для конкретной базы


...

...





Прочее


© Habrahabr.ru