Как Википедия говорит:
Liquibale — это независимая база данных с открытым исходным кодом для отслеживания, управления и применения изменений схемы базы данных. В 2006 году было начато в 2006 году, чтобы позволить более легкое отслеживание изменений базы данных, особенно в среде развития программного обеспечения Agile.
Я нахожу Liquibase в качестве аккуратного инструмента, чтобы автоматически перенести вашу базу данных. Сама миграция БД в любом случае очень сложная тема, за пределами объема этой статьи.
Liquibale может работать как автономный инструмент или его можно интегрировать в ваше приложение. Легко добавить его в пружинный контекст.
Весенний ботинок делает его еще проще. Liquibaase Autoconfigured Если вы включите его в файле свойств, у вас есть Liquibase в классе, а у вас есть Источник данных
в контексте.
liquibase.change-log=classpath:changelog.xml liquibase.enabled=true
Liquibale делает тестирование MOCKMVC очень простым. Можно настроить его для создания базы данных H2 для целей тестирования.
Liquibale гласит файл ChangeLog XML и показывает, что Смезы Это должно подать заявку. Используется Базы данныхChangeLog
Таблица в вашей БД ( DataSource
) для этой цели. Базы данныхChangeLog
Содержит список изменений, которые уже применяются с их ID
, Имя файла
, Md5sum
, Автор
и несколько других свойств.
Логика относительно проста. Просто, сравнивая изменяемый файл со столом Liquibase, знает, какие изменения его необходимо подать заявку. Есть, однако, немногие готы …
- Liquibale может принимать только один файл изменений
- Liquibale определяет список изменений для применения перед нанесением их
- Фактическая БД может выйти из синхронизации с
Базы данныхChangeLog
стол. Например. Если вы вручную изменяете базу данных, или так далее - Если Liquibase не может применить изменения, оно не сразу и не будет продолжаться с помощью следующих наборов данных
- Если Liquibase работает в пружинном приложении в качестве бона, он выполняется во время запуска приложения, следовательно, если он не удается, то Приложение не начнется
- Смезы не являются атомными. Это может случиться, что часть проходов изменений, она модифицирует БД правильно, а следующая часть не удалась. Запись набора изменений не пойдет в
Базы данныхChangeLog
стол. Следовательно, оно покидает БД в состоянии, который требует ручного ремонта (например, уверяет часть изменений и отпустить Liquibale снова) - Смезы не могут быть изменены. Если вы измените изменения, после того, как он был применен в вашей БД, то Liquibase не указывает, что MD5Sum не совпадает.
- Идентификатор не является уникальным идентификатором изменений. Это на самом деле комбинация
ID
,Имя файла
иАвтор
- Смешения, которые находятся в
Базы данныхChangeLog
и не в файлах изменений игнорируются
Конечно, Liquibase имеет гораздо больше функциональности. Просто прочитайте Документация Отказ Это также не имеет возможности этой статьи.
Да, если вы не определите некоторую стратегию в начале, ваш файл ChangeLog будет просто расти и больше. В большом проекте это может быть пару тысяч строк длиной с сотнями изменений. В файле ChangeLog есть высокий код Code, поэтому он приведет к тому, что у вас могут приложить возможность слияния усилий.
Есть несколько альтернатив, которые вы должны рассмотреть рано, чтобы избежать этого.
Определите несколько файлов изменений
.. и <включить>
Их в главном изменении, например.
Преимущество этого очевидна — меньше кода Churn, лучшая организация. Проблема наступает, если есть какие-либо логические зависимости между изменениями изменений в файлах — E.g. Если есть какие-либо отношения, определенные между таблицами нескольких файлов. Поскольку Liquibase выполняет изменения в последовательности, она начинается с Особенности1.xml
, продолжается с stature2.xml
Отказ
Возможно, вы можете узнать лучший сплит ключ — на основе целевых выпусков возможно?
Настройка нескольких прогонов Liquibase
Поскольку один прогон может принимать только один файл изменений, просто определите несколько файлов CHANGELOG и пусть Liquibase работает несколько раз.
В приложении вашего весеннего (загрузки) просто определите несколько Liquibase
бобы:
import liquibase.integration.spring.SpringLiquibase; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.DependsOn; import javax.sql.DataSource; @Configuration public class MultipleLiquiaseConfiguration { @Bean public SpringLiquibase liquibaseRelease1(DataSource dataSource) { SpringLiquibase liquibase = new SpringLiquibase(); liquibase.setDataSource(dataSource); liquibase.setChangeLog("classpath:release_v1.xml"); return liquibase; } @Bean public SpringLiquibase liquibaseRelease2(DataSource dataSource) { SpringLiquibase liquibase = new SpringLiquibase(); liquibase.setDataSource(dataSource); liquibase.setChangeLog("classpath:release_v2.xml"); return liquibase; } }
Обе бобы будут созданы в контексте, отсюда будет выполнено 2 прогона Liquibase. Если вы полагаетесь на автоконфигурацию весеннего ботинка, ваш Entitismanager
Бин заставит вас иметь один из бобов литка
. Это легко сделать. Кроме того, если ваши изменчивы должны работать в определенном порядке, вы можете решить это с помощью @Dependenson
:
@Configuration public class MultipleLiquiaseConfiguration { @Bean public SpringLiquibase liquibaseV1(DataSource dataSource) { SpringLiquibase liquibase = new SpringLiquibase(); liquibase.setDataSource(dataSource); liquibase.setChangeLog("classpath:release_v1.xml"); return liquibase; } @Bean @DependsOn("liquibaseV1") public SpringLiquibase liquibase(DataSource dataSource) { SpringLiquibase liquibase = new SpringLiquibase(); liquibase.setDataSource(dataSource); liquibase.setChangeLog("classpath:release_v2.xml"); return liquibase; } }
Обратите внимание, что последний для прогона называется Liquibase
(который ваш Entitymanager
зависит от), и он указывает на предыдущий до бега с @Dependenson
Аннотация.
Если вы не применили никакой стратегии в начале, или вы только что присоединились к запущенному проекту с Legacy Code, ваш изменяемый файл уже слишком большой. Теперь, как его уменьшить?
Вы можете сказать — ну, я просто разделил его на несколько файлов и использую любой из 2 стратегий, как упомянуто выше. Ну, не так быстро!:) Я упоминал ранее, что имя файла важно, так как он используется для определения того, применяются ли изменение или нет. Если вы просто переместите существующие изменения в другой файл, Liquibase подумает, что эти изменения не были применены, и на самом деле постарается снова применить их. И он потерпит неудачу, поскольку БД уже содержит изменения.
Чтобы описать проблему немного лучше, просто представьте себе модельную ситуацию, имеющую эту ChangeLog.xml
:
И вы перемещаете второе изменение на changelog2.xml
и включить changelog2.xml
в ChangeLog.xml
Отказ Запуск вашего приложения будет не удастся с аналогичным исключением:
Table "TABLE1" already exists;
Хорошо, он будет работать просто в ваших модульных тестах, поскольку БД создан с нуля, но выйдет из строя, если вы запустите Liquibase, чтобы перенести БД вашего развертываемого экземпляра. Мы все согласны с тем, что это плохо;)
К счастью, у нас осталось несколько вариантов;)
Изменить логикафилепат
Liquibale позволяет вам определить так называемый путь логического файла вашего ChangeLog. Это позволяет подделать Liquibalaze, что изменения изменений фактически приходят из одного файла. Представьте себе changelog2.xml
будет выглядеть так сейчас:
Обратите внимание на loficalfilepath
Значение там. Да, это будет работать, Liquibase будет относиться к этому Смешивания2.
Как будто он был ранее определен в ChangeLog.xml
Отказ Идеально.
На самом деле, этот подход имеет также несколько недостатков, которые могут (но не могли) остановить вас от применения. Если вы не храните свой изменяемый файл в ресурсах, а в другом месте в файловой системе, ваш Базы данныхChangeLog
будет содержать полный путь к файлу. Если у вас, у вас есть несколько сред, где вы хотите перенести дБ, и ваш файл ChangeLog файл варьируются, у вас нет способа, как установить logicalfilepath
Отказ Помните, что он должен соответствовать предыдущему значению.
Другой проблемой состоит в том, что этот подход не является лучшим, если ваше намерение разделить изменение изменений, заключается в том, чтобы переместить его часть в другой пакет, модуль и т. Д.
Используйте промежуточный изменяемый файл
Если вы намереваетесь перемещать часть вашего изменяющего значения в другой модуль (например, вы, наконец, хотите нарушить этот неприятный монолит от вас до нескольких микроэвиксов, имеющих свою собственную базу данных), этот подход может набирать вас лучшим. Он содержит некоторые промежуточные и временные шаги, но результат — это то, что вы хотите:)
Первым шагом является перемещение всех соответствующих изменений в другой файл в другом месте. В нашем примере выше мы просто перемещаем Изменение2
к changelog2.xml
Отказ Теперь нам нужно подделать Liquibale, что эти изменения из них не изменились. Мы делаем это по Изменение имени файла Значение в базе данных как часть самого изменения Liquibale;)
Создайте еще один (промежуточный/временный) изменяемый файл (давайте назовем это TMP-Migration.xml
Несомненно только с этим изменением:
UPDATE DATABASECHANGELOG SET FILENAME = REPLACE(FILENAME, 'changelog.xml', 'changelog2.xml')) WHERE ID IN ( 'changeset2' );
Это изменение заменит значение столбца имени файла в БД от Класс: changelog.xml
к Класс: changelog2.xml
Отказ Когда мы тогда запускаем Liquibasase с changelog2.xml
Это подумает, что все смены уже применяются. Невозможно использовать только 2 файлы Changelog для этой цели. Liquibale сначала вычисляет список изменений для применения (за файл изменений) и только тогда он будет применять их. Нам нужно изменить Имя файла
До этого обрабатывает второй файл.
Последний шаг, который мы должны подать заявку — это определить соответствующие бобы в нашем контексте в правильном порядке:
@Configuration public class MultipleLiquiaseConfiguration { @Bean public SpringLiquibase liquibaseChangelog(DataSource dataSource) { SpringLiquibase liquibase = new SpringLiquibase(); liquibase.setDataSource(dataSource); liquibase.setChangeLog("classpath:changelog.xml"); return liquibase; } @Bean @DependsOn("liquibaseChangelog") public SpringLiquibase liquibaseMigration(DataSource dataSource) { SpringLiquibase liquibase = new SpringLiquibase(); liquibase.setDataSource(dataSource); liquibase.setChangeLog("classpath:tmp-migration.xml"); return liquibase; } @Bean("liquibase") @DependsOn("liquibaseMigration") public SpringLiquibase liquibaseChangelog2(DataSource dataSource) { SpringLiquibase liquibase = new SpringLiquibase(); liquibase.setDataSource(dataSource); liquibase.setChangeLog("classpath:changelog2.xml"); return liquibase; } }
ChangeLog.xml
будет работать первым. Смешивания2 существуют в Базы данныхChangeLog
Но не в файле, следовательно, он игнорируется. Тогда TMP-Migration.xml
работает и меняет Имя файла
столбец. Последнее запустится changelog2.xml
, но Liquibase будет относиться к изменению2, как уже применяется.
Некоторое время спустя (когда вы считаете, что все затронутые базы данных уже мигрированы) Вы можете удалить TMP-Migration.xml
вместе с этим бобов. Изменение останется в Базы данныхChangeLog
стол, но это просто незначительная вещь, которую я верю.
И затем следующим шагом может быть перемещение определения бобов к контекстам ваших бетонных микросервисов.
Всегда есть как-то путь;)
Оригинал: «https://dev.to/vladonemo/splitting-liquibase-changelong-no-problem-2a4l»