Liquibase с Spring Boot и несколькими схемами, как указать порядок выполнения - PullRequest
0 голосов
/ 11 февраля 2019

У нас есть задание по переносу данных, которое должно инициализировать схемы A и B в указанном порядке.Мы обрабатываем несколько схем, определяя несколько SpringLiquibase, по одной для каждой схемы, каждая со своим собственным источником данных и собственным основным набором изменений.(Обратите внимание, что обычно в Spring Boot вам не нужно определять SpringLiquibase, потому что он будет обнаруживать один источник данных и автоматически настраивать SpringLiquibase для вас с этим источником данных.)

Порядок выполнения, кажется, различается в зависимости отвыполняется ли задание локально в среде IDE или связывается как приложение Spring Boot с одним JAR.

Как мы можем гарантировать, что два выполнения liquibase происходят в нужном нам порядке?

(Почему порядок важен: A содержит несколько таблиц, а B содержит представления, которые ссылаются на таблицы в A. Мы должны убедиться, что мы grant select on A.* to B, прежде чем пытаться create view B.some_view (...) as select ... from A.xyz, в противном случае создание Bне удается из-за недостаточных привилегий.)

Ответы [ 2 ]

0 голосов
/ 11 февраля 2019

Это не для весенней загрузки, но если вы управляете миграциями через журналы изменений, этот обходной путь поможет.Это предполагает, что у вас есть разные источники данных для разных схем.

<bean id="liquibase1" class="liquibase.integration.spring.SpringLiquibase">
      <property name="dataSource" ref="dataSource1" />
      <property name="changeLog" value="classpath:db1-changelog1.xml" />
 </bean>
 <bean id="liquibase2" depends-on="liquibase1" class="liquibase.integration.spring.SpringLiquibase">
      <property name="dataSource" ref="dataSource2" />
      <property name="changeLog" value="classpath:db2-changelog1.xml" />
 </bean>
<bean id="liquibase3" depends-on="liquibase2"  class="liquibase.integration.spring.SpringLiquibase">
      <property name="dataSource" ref="dataSource1" />
      <property name="changeLog" value="classpath:db1-changelog2.xml" />
 </bean>
<bean id="liquibase4" depends-on="liquibase3"  class="liquibase.integration.spring.SpringLiquibase">
      <property name="dataSource" ref="dataSource2" />
      <property name="changeLog" value="classpath:db2-changelog2.xml" />
 </bean>
0 голосов
/ 11 февраля 2019

После некоторого расчесывания головок и копания в исходном коде это оказывается чрезвычайно простым.

SpringLiquibase реализует InitializingBean и выполняет обновление Liquibase в методе InitializingBean.afterPropertiesSet().

Spring вызывает этот метод для каждого bean-компонента один за другим после завершения инициализации каждого.

Таким образом, чтобы форсировать определенный порядок, вам нужно установить порядок, в котором bean-компоненты определены в контексте Spring.И самый простой способ сделать это с аннотацией @DependsOn.

Итак, мы добавили что-то вроде:

@Bean
public SpringLiquibase liquibaseA(
    @Qualifier("dataSourceA") DataSource dataSource,
    @Qualifier("liquibasePropertiesA") LiquibaseProperties liquibaseProperties
) {
    return instantiateSpringLiquibase(dataSource, liquibaseProperties); 
}

@Bean
@DependsOn("liquibaseA")
public SpringLiquibase liquibaseB(
    @Qualifier("dataSourceB") DataSource dataSource,
    @Qualifier("liquibasePropertiesB") LiquibaseProperties liquibaseProperties
) {
    return instantiateSpringLiquibase(dataSource, liquibaseProperties); 
}

private SpringLiquibase instantiateSpringLiquibase(DataSource dataSource, LiquibaseProperties liquibaseProperties) {
    // set the datasource from dataSource and everything else from liquibaseProperties
}
...