[Из песочницы] Liqubase и Maven
Введение
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 — он уже содержит все необходимые зависимости, настройки и профили.
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
Обработка типов данных специфичних для конкретной базы
...
...
Прочее