Flyway版本化管理数据库脚本

假如我们有一个叫shiny的项目,它是由一个程序Shiny-Server 和一个数据库 Shiny-DB组成的;

简单结构图如下:

Flyway版本化管理数据库脚本

但是很多时候,现实开发团队是这样的:

Flyway版本化管理数据库脚本

我们的项目shiny项目的运行环境是有多套的,

我们擅长解决代码层面的问题。

版本控制工具git非常普遍而且好用

我们有持续集成和持续构建的工具

我们很好的定义了测试和生产环境的发布流程

Flyway版本化管理数据库脚本

但是我们的数据库的版本如何控制呢?

Flyway版本化管理数据库脚本

 当前现状

非常不幸的是我们还不能很好的处理数据库的版本管理问题,

很多的项目依赖运维人员手动的执行SQL脚本,

有的时候甚至为了快速解决bug去快速的在命令行上执行SQL脚本,那么问题来了。

Flyway版本化管理数据库脚本

通常这些问题的答案是:鬼知道。

引入目的

flyway解决了上面的这些问题。

Flyway版本化管理数据库脚本

目前Flyway支持的数据库还是挺多的,包括:

Oracle, SQL Server, SQL Azure, DB2, DB2 z/OS,

MySQL(including Amazon RDS), MariaDB,

Google Cloud SQL, PostgreSQL(including Amazon RDS and Heroku),

Redshift, Vertica, H2, Hsql, Derby, SQLite, SAP HANA,

solidDB, Sybase ASE and Phoenix。

 Flyway的执行流程

Flyway是一款开源的数据库版本管理工具,

它更倾向于规约优于配置的方式。

Flyway可以独立于应用实现管理并跟踪数据库变更,支持数据库版本自动升级,

并且有一套默认的规约,不需要复杂的配置,

Migrations可以写成SQL脚本,也可以写在Java代码中,

不仅支持Command Line和Java API,还支持Build构建工具和Spring Boot等,

同时在分布式环境下能够安全可靠地升级数据库,同时也支持失败恢复等。

Flyway版本化管理数据库脚本

每次不管是数据库的表结构或者表数据的变更,

你只需要把问题当成一次数据库的升级,

简单的创建一个比当前版本更高的版本的迁移SQL文件或者Java文件,

下次Flyway启动的时候,他会找到这些脚本并把它更新到数据库。

脚本或者Java迁移脚本的命名规则:

Flyway版本化管理数据库脚本

其中的文件名由以下部分组成,除了使用默认配置外,某些部分还可自定义规则。

– prefix: 可配置,前缀标识,默认值`V`表示Versioned,`R`表示Repeatable

– version: 标识版本号,由一个或多个数字构成,数字之间的分隔符可用点`.`或下划线`_`

– separator: 可配置,用于分隔版本标识与描述信息,默认为两个下划线`__`

– description: 描述信息,文字之间可以用下划线或空格分隔

– suffix: 可配置,后续标识,默认为`.sql`

实现路径

Flyway版本化管理数据库脚本

真实项目版本更新场景中,我们不可能再基于人力去做这件事情,我们选择的是**API**的方式。

使用步骤如下:

Flyway版本化管理数据库脚本

一般大家都是写SQL脚本,也支持通过写Java代码的方式来实现。

 Java方式写迁移功能

Flyway版本化管理数据库脚本

使用步骤:

Flyway版本化管理数据库脚本

目前的集成方式

使用的是springboot的方式集成了Flyway;

Flyway版本化管理数据库脚本

配置参数:可自行翻译和参考选择去配置

flyway.baseline-description= # The description to tag an existing schema with when executing baseline.
flyway.baseline-version=1 # Version to start migration.
flyway.baseline-on-migrate=false # Whether to execute migration against a non-empty schema with no metadata table
flyway.check-location=false # Check that migration scripts location exists.
flyway.clean-on-validation-error=false # will clean all objects. Warning! Do NOT enable in production!
flyway.enabled=true # Enable flyway.
flyway.encoding=UTF-8 # The encoding of migrations.
flyway.ignore-failed-future-migration=true # Ignore future migrations when reading the metadata table.
flyway.init-sqls= # SQL statements to execute to initialize a connection immediately after obtaining it.
flyway.locations=classpath:db/migration # locations of migrations scripts.
flyway.out-of-order=false # Allows migrations to be run "out of order".
flyway.placeholder-prefix=  # The prefix of every placeholder.
flyway.placeholder-replacement=true # Whether placeholders should be replaced.
flyway.placeholder-suffix=} # The suffix of every placeholder.
flyway.placeholders.*= # Placeholders to replace in Sql migrations.
flyway.schemas= # Default schema of the connection and updating
flyway.sql-migration-prefix=V # The file name prefix for Sql migrations
flyway.sql-migration-separator=__ # The file name separator for Sql migrations
flyway.sql-migration-suffix=.sql # The file name suffix for Sql migrations
flyway.table=schema_version # The name of Flyway\'s metadata table.
flyway.url= # JDBC url of the database to migrate. If not set, the primary configured data source is used.
flyway.user= # Login user of the database to migrate. If not set, use spring.datasource.username value.
flyway.password= # JDBC password if you want Flyway to create its own DataSource.
flyway.validate-on-migrate=true # Validate sql migration CRC32 checksum in classpath.
package db.migration;
/**
 * @author carter
 * create_date  2020/8/13 17:39
 * description     java数据库变更模板代码
 */
import lombok.extern.slf4j.Slf4j;
import org.flywaydb.core.api.migration.BaseJavaMigration;
import org.flywaydb.core.api.migration.Context;
import java.sql.ResultSet;
import java.sql.Statement;
@Slf4j
public class V2__test extends BaseJavaMigration {
    @Override
    public void migrate(Context context) throws Exception {
        try (Statement select = context.getConnection().createStatement()) {
            try (ResultSet rows = select.executeQuery("SELECT 1")) {
                while (rows.next()) {
                    int id = rows.getInt(1);
                    String anonymizedName = "Anonymous"   id;
                    log.info("执行sql脚本:{}",anonymizedName);
                }            }        }    }}

内容出处:,

声明:本网站所收集的部分公开资料来源于互联网,转载的目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。如果您发现网站上有侵犯您的知识产权的作品,请与我们取得联系,我们会及时修改或删除。文章链接:http://www.yixao.com/procedure/10661.html

发表评论

登录后才能评论