在我的 Spring boot 项目中,我通过
sql/query
维护 flyway
版本。由于某种原因,我需要加载一些我不想在 Flyway 版本上添加的初始数据。对于这些数据,我正在从 flyway
脚本创建相关表。因此,要加载初始数据,我必须在 Flyway 执行该脚本后运行我的 data.sql
文件。在 Flyway 运行其脚本后,如何确保运行我的 data.sql
文件?
请问有什么建议吗?
data.sql
对于嵌入式数据库自动运行。
对于 MySQL,您需要将以下属性添加到您的
application.properties
文件中:
spring.datasource.initialization-mode=always
编辑:
要在 Flyway 运行迁移后应用,您可以使用 Flyway 的可重复迁移,因为它们总是最后应用。 https://flywaydb.org/documentation/migrations#repeatable-migrations
或者作为另一种选择,您可以使用
CommandLineRunner
和源并以编程方式执行 SQL 文件。例如:
import org.springframework.boot.CommandLineRunner;
@Component
public class DatabaseMigration implements CommandLineRunner {
@Value("classpath:data.sql")
private Resource dataFile;
@Override
public void run(String... strings) {
// read file and execute with JdbcTemplate
// ...
}
}
示例
import lombok.Getter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
@Configuration
@Getter
public class FlywayConfiguration {
@Value("${spring.flyway.url}") private String link;
@Value("${spring.flyway.user}") private String user;
@Value("${spring.flyway.password}") private String password;
@Value("${spring.flyway.table}") private String table;
@Value("${spring.flyway.default-schema}") private String defaultSchema;
@Value("${spring.flyway.schemas}") private String schemas;
@Value("${migrate.target}") private String target;
}
import lombok.Getter;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.flywaydb.core.Flyway;
import org.flywaydb.core.api.configuration.FluentConfiguration;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.sql.CallableStatement;
@Slf4j
@Component
@Getter
public class FlywayInstance {
private final Flyway flyway;
private final FlywayConfiguration flywayConfiguration;
FlywayInstance(FlywayConfiguration flywayConfiguration) {
FluentConfiguration flyway = Flyway.configure()
.dataSource(flywayConfiguration.getLink(), flywayConfiguration.getUser(), flywayConfiguration.getPassword())
.table(flywayConfiguration.getTable())
.defaultSchema(flywayConfiguration.getDefaultSchema())
.schemas(flywayConfiguration.getSchemas());
if (!flywayConfiguration.getTarget().isBlank()) {
flyway.target(flywayConfiguration.getTarget());
}
// flyway = flyway
// .initSql("INSERT INTO base.data(name)\n" +
// " VALUES ('bobo4');");
this.flyway = flyway.load();
this.flywayConfiguration = flywayConfiguration;
}
@PostConstruct()
public void validateConnection() {
log.info(String.format("Checking connection on startup for %s", this.flywayConfiguration.getLink()));
log.info(String.format("Connected. Version: %s, Migrations: %d",
flyway.info().getInfoResult().schemaVersion,
flyway.info().getInfoResult().migrations.size()));
}
@SneakyThrows
public boolean execute(String call) {
final CallableStatement callableStatement = this.flyway
.getConfiguration()
.getDataSource()
.getConnection()
.prepareCall(call);
return callableStatement.execute();
}
}
通过execute你可以运行ddl。至少创建表格对我有用。
一种可能的解决方案是简单地使用 afterMigrate Flyway 回调。并将这些测试数据插入到测试/资源中