提醒:这个项目是一个概念验证的Demo,仅支持的数据库为Postgresql。
Dust受到了Truffle的启发,后者是一个专注于以太坊智能合约的开发框架,可以方便的开发、测试和部署智能合约。
长期以来,在数据库开发领域缺少一种通用的开发工具,可以方便地将数据库开发相关的内容进行有效地管理,形成开发、测试、部署的完整闭环。DB Migration实践虽然在一定程度上解决了这个问题,但它是作为敏捷开发项目实践的补充,并非专门针对数据库开发。
Dust的出现将终结这种境况。使用Dust,数据库的开发不再游离于正规的软件开发过程之外,所有与开发有关的数据库代码将通过它进行统一的管理。整个开发流程如下:
- 创建Dust工程。
- 开发数据库制品,如表、存储过程、函数、任务、触发器等。
- 完成相应的测试代码。
- 本地运行测试。
- 部署数据库制品到不同的环境。
不仅仅如此,Dust还可以与目前广为接受的持续集成有机结合,成为整个开发部署流水线的一环。
Dust的诞生离不开成功开源软件的支持:
- cli,picocli
- 自动化测试,spock
- 本地数据库测试环境,testcontainers
- 轻量级的DB Migration工具,flyway
假设已经安装了java和gradle,通过源码编译和安装步骤如下:
- git clone < dust 代码仓库>
- 方法1:
- gradlew installdist,它将在工程的 build/install/dust/ 下安装,bin目录下为可执行文件
- 方法2:生成安装包
- gradlew distTar/distZip,将生成tar或zip的安装包
- 创建工程:dust create app_name,它将创建dust工程目录(它本质上是一个gradle工程),主要结构如下:
- README.md,readme文件
- artifacts,数据库制品目录
- migrations,迁移脚本目录
- test,测试代码目录
- dust-config.json,dust配置文件
- build.gradle,gradle build文件
- 进入工程目录:cd app_name
- 在artifacts目录下创建所需数据库制品,如表或存储过程之类,建议每个制品一个文件。
- 在test目录下创建测试代码,测试代码为spock specification。这个目录下包含相应的一些示例代码,展示了spock和testcontainer的使用。
- 运行测试:dust test
- 在migrations目录创建迁移脚本,迁移脚本的命名格式如下:V版本__描述.java,如:V1__CreateUser.java。迁移脚本内容类似:
public class V1__CreateUser extends DustBaseMigration { @Override protected String[] files() { return new String[]{ "./artifacts/myuser.sql" // 数据制品文件名 }; } }
- 部署制品:dust deploy
目前配置文件(dust-conf.json),主要的作用就是定义deploy命令的不同数据源。这些不同数据源可视为不同的部署环境,典型的配置文件内容如下:
{
"development": {
"url": "jdbc:postgresql://127.0.0.1:5432/earth_test?useUnicode=true&characterEncoding=utf8",
"user": "earth_admin",
"password": "admin"
},
"production": {
"url": "jdbc:postgresql://127.0.0.1:5432/jupiter_test?useUnicode=true&characterEncoding=utf8",
"user": "jupiter_admin",
"password": "admin"
}
}
你也可以定义自己的数据源名称,如myds,在上述文件里添加:
"myds": {
"url": "myurl",
"user": "myuser",
"password": "mypassword"
}
dust支持多数据库环境,这样可以将测试和产品环境进行有效隔离。数据源定义在dust-config.json中,通过指定不同的远程数据源定义名即可:
dust deploy --datasource myds
如不指定 --datasource,则缺省为 development。
测试基于testcontainers完成,由于采用了jdbc,因此,理论上testcontainers中支持的数据库,dust都应该支持。目前作为原型demo,dust仅仅只支持postgresql,如果想要将其应用于其他数据库,请做如下改动:
- 按照上面的命令生成相应的 dust 工程。
- 在build.gradle中替换如下行:
runtime 'org.postgresql:postgresql:42.2.5' testCompile "org.testcontainers:postgresql:1.10.6"
- 在test中使用所选数据库对应的testcontainer,实际例子可以参照 /test/DatabaseSpec.groovy。
部署脚本放置于 migrations 目录,不要删除或修改以下几个文件:
- DustBaseMigration.java
- DustConfiguration.groovy
- MigrationApp.java
迁移脚本中要求实现的 files() ,其指定了数据库制品的执行顺序,甚至你也可以在 artifacts 目录下添加数据初始化文件,然后通过部署脚本完成部署。如:
@Override
protected String[] files() {
return new String[]{
"./artifacts/myuser.sql", // 创建 myuser 表
"./artifacts/insert_myuser.sql", // 插入数据
};
}
由于迁移脚本采用的是 flyway 的 Java-based migrations ,若发现当前提供的 DustBaseMigration 类无法满足你的要求,请直接使用 flyway 提供的相应工具类。同时,dust也采用了 flyway 的命名规范。我个人推荐“Versioned Migrations”,不建议采用“Repeatable Migrations”。因为在实际情况中,后者使得制品历史消失了,本身已经违背了引入Migration的目的。而且,DML类的变动总涉及到数据的迁移,因此坚持“一直前向”是最适合的策略。而且,为了避免频繁修改脚本,我建议不要在项目早期引入dbmigration,而是待数据库制品都相对稳定时,再开始不迟。
dust在迁移时会自动baseline,同时设置迁移版本为0,因此创建迁移脚本时V后的数字务必大于0。