Multiple datasources migrations using Flyway in a Spring Boot application

后端 未结 4 521
刺人心
刺人心 2020-12-31 03:39

We use Flyway for db migration in our Spring Boot based app and now we have a requirement to introduce multi tenancy support while using multiple datasources strategy. As pa

相关标签:
4条回答
  • 2020-12-31 04:02

    Having your same problem... I looked into the spring-boot-autoconfigure artifact for V 2.2.4 in the org.springframework.boot.autoconfigure.flyway package and I found an annotation FlywayDataSource.

    Annotating ANY datasource you want to be used by Flyway should do the trick.
    Something like this:

    @FlywayDataSource
    @Bean(name = "someDatasource")
    public DataSource someDatasource(...) {
            <build and return your datasource>
    }
    
    0 讨论(0)
  • 2020-12-31 04:06

    Flyway supports migrations coded within Java and so you can start Flyway during your application startup.

    https://flywaydb.org/documentation/migration/java
    

    I am not sure how you would config Flyway to target a number of data sources via the its config files. My own development is based around using Java to call Flyway once per data source I need to work against. Spring Boot supports the autowiring of beans marked as @FlywayDataSource, but I have not looked into how this could be used.

    For an in-java solution the code can be as simple as

        Flyway flyway = new Flyway();
    
        // Set the data source
        flyway.setDataSource(dataSource);
    
        // Where to search for classes to be executed or SQL scripts to be found
        flyway.setLocations("net.somewhere.flyway");
    
        flyway.setTarget(MigrationVersion.LATEST);
        flyway.migrate();
    
    0 讨论(0)
  • 2020-12-31 04:15

    To make @Roger Thomas answer more the Spring Boot way:

    Easiest solution is to annotate your primary datasource with @Primary (which you already did) and just let bootstrap migrate your primary datasource the 'normal' way.

    For the other datasources, migrate those sources by hand:

    @Configuration
    public class FlywaySlaveInitializer {
    
         @Autowired private DataSource dataSource2;
         @Autowired private DataSource dataSource3;
         //other datasources
    
         @PostConstruct
         public void migrateFlyway() {
             Flyway flyway = new Flyway();
             //if default config is not sufficient, call setters here
    
             //source 2
             flyway.setDataSource(dataSource2);
             flyway.setLocations("db/migration_source_2");
             flyway.migrate();
    
             //source 3
             flyway.setDataSource(dataSource3);
             flyway.setLocations("db/migration_source_3");
             flyway.migrate();
         }
    }
    
    0 讨论(0)
  • 2020-12-31 04:17

    Found an easy solution for that - I added the step during the creation of my emf:

    @Qualifier(EMF2)
    @Bean(name = EMF2)
    public LocalContainerEntityManagerFactoryBean entityManagerFactory2(
        final EntityManagerFactoryBuilder builder
    ) {
        final DataSource dataSource = dataSource2();
        Flyway.configure()
              .dataSource(dataSource)
              .locations("db/migration/ds2")
              .load()
              .migrate();
        return builder
            .dataSource(dataSource)
            .packages(Role.class)
            .properties(jpaProperties2().getProperties())
            .persistenceUnit("domain2")
            .build();
    }
    

    I disabled spring.flyway.enabled for that.

    SQL files live in resources/db/migration/ds1/... and resources/db/migration/ds2/...

    0 讨论(0)
提交回复
热议问题