当前位置: 首页 > 知识库问答 >
问题:

Spring Boot Flyway将数据库迁移应用到错误的数据库

卓胜
2023-03-14

我正在尝试配置Spring Boot和Flyway,以便使用Spring Boot 2.2.6和Flyway 5.2.3对两个不同的数据源应用单独的迁移。

主要数据源:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = {"com.gobsmack.*.repository.primary"},
                       entityManagerFactoryRef = "primaryEntityManagerFactory",
                       transactionManagerRef = "primaryTransactionManager"
)
public class PrimaryDatasourceConfiguration {

    @Bean
    @Primary
    @ConfigurationProperties(prefix = "spring.primary-datasource")
    public DataSource primaryDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Primary
    @Bean(name = "primaryEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean primaryEntityManagerFactory(EntityManagerFactoryBuilder builder) {
        return builder.dataSource(primaryDataSource())
                .packages("com.gobsmack.*.model")
                .build();
    }

    @Primary
    @Bean
    public PlatformTransactionManager primaryTransactionManager(
            final @Qualifier("primaryEntityManagerFactory") LocalContainerEntityManagerFactoryBean primaryEntityManagerFactory) {
        return new JpaTransactionManager(primaryEntityManagerFactory.getObject());
    }
}

第二个数据源:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = {"com.gobsmack.*.repository.secondary"},
                       entityManagerFactoryRef = "secondaryEntityManagerFactory",
                       transactionManagerRef = "secondaryTransactionManager"
)
public class SecondaryDatasourceConfiguration {

    @Bean
    @ConfigurationProperties(prefix = "spring.secondary-datasource")
    public DataSource secondaryDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "secondaryEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean secondaryEntityManagerFactory(EntityManagerFactoryBuilder builder) {
        return builder.dataSource(secondaryDataSource())
                .packages("com.gobsmack.*.model")
                .build();
    }

    @Bean
    public PlatformTransactionManager secondaryTransactionManager(
            final @NonNull @Qualifier("secondaryEntityManagerFactory") LocalContainerEntityManagerFactoryBean secondaryEntityManagerFactory) {
        return new JpaTransactionManager(secondaryEntityManagerFactory.getObject());
    }
}

数据源连接属性:

spring:
  primary-datasource:
    jdbc-url: jdbc:mysql://localhost:3306/primary?useSSL=false&primary
    password: password
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: username
  secondary-datasource:
    jdbc-url: jdbc:mysql://localhost:3306/secondary?useSSL=false&secondary
    password: password
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: username

Flyway迁移:

@Slf4j
@Configuration
public class FlywayConfiguration {

    public static final String DB_MIGRATION_BASE = "db/migration/";

    private DataSource primaryDataSource;
    private DataSource secondaryDataSource;

    @Value("${spring.primary-datasource.jdbc-url:localhost}")
    private String primaryDatasourceUrl;

    @Value("${spring.secondary-datasource.jdbc-url:localhost}")
    private String secondaryDatasourceUrl;

    @Autowired
    public FlywayConfiguration(@Qualifier("primaryDataSource") DataSource primaryDataSource,
                               @Qualifier("secondaryDataSource") DataSource secondaryDataSource) {
        this.primaryDataSource = primaryDataSource;
        this.secondaryDataSource = secondaryDataSource;
    }

    @PostConstruct
    public void migrate() {
        log.info("Preparing Flyway migration for database with url: " + primaryDatasourceUrl);
        migrateDatabase(primaryDataSource, "primary");

        log.info("Preparing Flyway migration for database with url: " + secondaryDatasourceUrl);
        migrateDatabase(secondaryDataSource, "secondary");
    }

    /**
     * Migrate specific database.
     * @param datasource The datasource.
     * @param directories The directories containing the migration scripts.
     */
    private void migrateDatabase(@NonNull DataSource datasource, @NonNull String... directories) {
        for (val directory : directories) {
            log.info("Migration scripts source: " + directory);
            new Flyway(Flyway.configure()
                             .dataSource(datasource)
                             .locations(DB_MIGRATION_BASE + directory))
                             .migrate();
        }
    }
}

目录结构:

迁移脚本v1.0.0_1__secondary__init.sql仅正确应用于secondary数据库。

问题是,db/migration/primarydb/migration/secondary中的脚本被应用到primary数据库,而只应用主目录中的脚本。

如何配置Flyway以仅将db/migration/primary目录中的迁移脚本应用于primary数据库?

共有1个答案

徐知
2023-03-14

我必须禁用Flyway的自动运行,因为它正在查找应用于@primary注释数据库的脚本。它正在db/migration子目录中查找所有迁移脚本。

因此,在application.yml配置文件中,我必须添加:

spring:
  flyway:
    enabled: false
 类似资料:
  • 本文向大家介绍Django 将更改应用到数据库(迁移),包括了Django 将更改应用到数据库(迁移)的使用技巧和注意事项,需要的朋友参考一下 示例 创建新模型或修改现有模型后,您将需要为更改生成迁移,然后将迁移应用于指定的数据库。这可以通过使用Django的内置迁移系统来完成。manage.py在项目根目录中使用实用程序: 上面的命令将在migrations应用程序的子目录下创建必需的迁移脚本。

  • 我有两个表,事务表和付款表,它们在过去的迁移中已经存在。当我试图在它们之间建立一个透视表时,只会得到事务外键的一个错误。“payments”表上的另一个外键创建得很好。这绝对让我感到困惑,我之前关于这个错误的讨论都没有解决这个问题。 错误(参考,MAccounting是数据库的名称): *尽管错误似乎说,payment_transaction表创建成功,以及支付表的外键;唯一中断的是交易的外键。

  • move key db-index 返回1成功。0 如果key不存在,或者已经在指定数据库中

  • 问题内容: 我正在使用Java开发数据库迁移工具。该工具将数据库表及其数据复制到目标数据库。但是我希望它可以在不同的数据库上工作。从mysql复制并在derby等中创建。使用JDBC,我们可以收集有关表及其列的足够信息。但是我要问的是,是否可以使用sql free在Java上重新创建表。我的意思是不同的数据库具有不同的数据类型,有时它们在sql语法上也有所不同。那么JDBC或任何其他库(可以是开放

  • 在开发和维护一个数据库驱动的应用程序时, 数据库的结构会像代码一样不断演变。 例如,在开发应用程序的过程中,会增加一张新表且必须得加进来; 在应用程序被部署到生产环境后,需要建立一个索引来提高查询的性能等等。 因为一个数据库结构发生改变的时候源代码也经常会需要做出改变, Yii 提供了一个 数据库迁移 功能,该功能可以记录数据库的变化, 以便使数据库和源代码一起受版本控制。 如下的步骤向我们展示了

  • 简介 迁移就像是数据库的版本控制, 允许团队简单轻松的编辑并共享应用的数据库表结构,迁移通常和 Laravel 的 数据库结构生成器配合使用,让你轻松地构建数据库结构。如果你曾经试过让同事手动在数据库结构中添加字段,那么数据库迁移可以让你不再需要做这样的事情。 Laravel 的 Schema 门面 对所有 Laravel 支持的数据库系统提供了创建和操作数据表的相应支持。 生成迁移 使用 Art