处理许多客户在许多生产环境中部署的产品.它包括至少一个Spring Boot应用程序.
我们使用flyway进行数据库模式迁移.从Spring Boot 1.5.x升级到2.0.x已将我们的flyway版本从3.x升级到5.x.
Spring Boot迁移指南简单地说是在引导升级之前升级到flyway 4.但是,这需要我们的所有客户在升级到最新版本之前进行中间升级.
所以,问题是:如何将你从飞路3直接升级到迁飞5?
步骤 0。
升级到 spring boot v2.1(然后隐式升级到 flyway 5)。
第1步。
由于schema_version在 flyway 3.x 中使用,让新的 flyway 版本知道他们应该继续使用这个表。:
# application.yml
spring.flyway.table: schema_version # prior flyway version used this table and we keep it
Run Code Online (Sandbox Code Playgroud)
第2步。
src/main/ressources/db/migration/flyway_upgradeMetaDataTable_V3_to_V4.sql根据您使用的方言创建用于升级元表的文件。
这是 postgres 的一个,假设飞行表名称是schema_version:
-- src/main/ressources/db/migration/flyway_upgradeMetaDataTable_V3_to_V4.sql
DROP INDEX "schema_version_vr_idx";
DROP INDEX "schema_version_ir_idx";
ALTER TABLE "schema_version" DROP COLUMN "version_rank";
ALTER TABLE "schema_version" DROP CONSTRAINT "schema_version_pk";
ALTER TABLE "schema_version" ALTER COLUMN "version" DROP NOT NULL;
ALTER TABLE "schema_version" ADD CONSTRAINT "schema_version_pk" PRIMARY KEY ("installed_rank");
UPDATE "schema_version" SET "type"='BASELINE' WHERE "type"='INIT';
Run Code Online (Sandbox Code Playgroud)
第 3 步。
创建 Java 文件 your.package/FlywayUpdate3To4Callback.java
请注意,这会执行以下操作:
Flyway.repair()// FlywayUpdate3To4Callback.java
package your.package;
import static org.springframework.core.Ordered.HIGHEST_PRECEDENCE;
import org.flywaydb.core.Flyway;
import org.flywaydb.core.api.callback.Callback;
import org.flywaydb.core.api.callback.Context;
import org.flywaydb.core.api.callback.Event;
import org.flywaydb.core.api.configuration.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.jdbc.datasource.init.ScriptUtils;
import org.springframework.jdbc.support.JdbcUtils;
import org.springframework.jdbc.support.MetaDataAccessException;
import org.springframework.stereotype.Component;
import lombok.extern.slf4j.Slf4j;
@Component
@Order(HIGHEST_PRECEDENCE)
@Slf4j
public class FlywayUpdate3To4Callback implements Callback {
private final Flyway flyway;
public FlywayUpdate3To4Callback(@Lazy Flyway flyway) {
this.flyway = flyway;
}
private boolean checkColumnExists(Configuration flywayConfiguration) throws MetaDataAccessException {
return (boolean) JdbcUtils.extractDatabaseMetaData(flywayConfiguration.getDataSource(),
callback -> callback
.getColumns(null, null, flywayConfiguration.getTable(), "version_rank")
.next());
}
@Override
public boolean supports(Event event, Context context) {
return event == Event.BEFORE_VALIDATE;
}
@Override
public boolean canHandleInTransaction(Event event, Context context) {
return false;
}
@Override
public void handle(Event event, Context context) {
boolean versionRankColumnExists = false;
try {
versionRankColumnExists = checkColumnExists(context.getConfiguration());
} catch (MetaDataAccessException e) {
log.error("Cannot obtain flyway metadata");
return;
}
if (versionRankColumnExists) {
log.info("Upgrading metadata table the Flyway 4.0 format ...");
Resource resource = new ClassPathResource("db/migration/common/flyway_upgradeMetaDataTable_V3_to_V4.sql",
Thread.currentThread().getContextClassLoader());
ScriptUtils.executeSqlScript(context.getConnection(), resource);
log.info("Flyway metadata table updated successfully.");
// recalculate checksums
flyway.repair();
}
}
}
Run Code Online (Sandbox Code Playgroud)
第四步。
运行弹簧靴。
日志应显示类似于以下内容的信息消息:
...FlywayUpdate3To4Callback : Upgrading metadata table the Flyway 4.0 format
...FlywayUpdate3To4Callback : Flyway metadata table updated successfully.
Run Code Online (Sandbox Code Playgroud)
学分
此答案基于 Eduardo Rodrigues 的答案,通过更改:
Event.BEFORE_VALIDATE触发飞路回调升级飞行用3〜4。如果我不是地球上最后一个仍要从3升级到5的人。
问题:
我希望升级对项目中的其他开发人员来说是透明的,并且在实时应用程序上升级时不需要任何特殊的部署说明,所以我做了以下工作。
我看了第4版如何处理升级:
这很容易手动完成,但使其透明。该应用程序是一个Spring应用程序,但不是Spring Boot应用程序,因此,当我让flyway在应用程序启动时通过依赖于flyway bean的LocalContainerEntityManagerBean构造自动在应用程序启动时运行迁移,该迁移方法将其称为init方法(在此处说明Flyway) Spring JPA2集成-是否可以进行模式验证?),因此引导的顺序为:
Flyway bean created -> Flyway migrate called -> LocalContainerEntityManager created
Run Code Online (Sandbox Code Playgroud)
解:
我将引导程序的顺序更改为:
Flyway bean created -> Flyway3To4Migrator -> LocalContainerEntityManager created
Run Code Online (Sandbox Code Playgroud)
如果需要,Flyway3To4Migrator将在其中执行schema_table更改,如果升级发生,请运行修复,然后始终运行flyway.migrate继续迁移。
Flyway bean created -> Flyway migrate called -> LocalContainerEntityManager created
Run Code Online (Sandbox Code Playgroud)
注意事项: