使用 dbdeploy.net 管理数据库变更

没有包含数据库的持续集成都是假的。这可不是我说的。
一直以来都没能找到一个理想的数据库变更管理工具。直到转了 java 再回来,才发现 dbdeploy 是有.net 版的。赶紧尝试一下。

一、工具
先是从 sourceForge 上下载了成品,试运行发现找不到依赖的 dll,而且版本也比较老(2013年构建的)。想到要是有源码编译一份就好了。从 github 上搜索 dbdeploy.net,第一个就是,除了源码外还有详细的使用说明,实在太重要了。

把源码拿下来编译(用的 vs2013)也是编译不过,提示找不到依赖包。用 nuget 管理了一下包,终于编译通过。从 Dbdeploy.Console\bin\Debug 下拿到完整的工具。接下来开始使用。

二、配置
根据 github 上的使用说明,运行时可以直接使用命令行,也可以使用配置文件。感觉上还是配置文件更方便管理。在 debug 下创建 run.bat 和 run.config.xml. 两个文件的内容如下:

run.bat
---------------------------------------------------------
dbdeploy.exe --config=run.config.xml
---------------------------------------------------------

run.config.xml
---------------------------------------------------------
<?xml version="1.0" encoding="utf-8" ?>
<!-- Multiple deployments can be executed. -->
<config>
  <dbdeployments>

<!-- Run with all options. -->
    <dbdeploy
        dbms="mysql"
        connectionString="Server=127.0.0.1; port=3306; Initial Catalog=testdb;User Id=root;Password=root"
        scriptDirectory="..\src"
        outputFile="..\target\changes.sql"
        changeLogTableName="changelog"
        autoCreateChangeLogTable="true"
        forceUpdate="false"
        useSqlCmd="true"
        encoding="UTF-8"
        templateDirectory="Resources"
        delimiter=";"
        delimiterType="row"
        lineEnding="LF"
        />
  </dbdeployments>
</config>
---------------------------------------------------------

说明:
1. 数据库是 mysql
2. 所有的数据库变更脚本在 ../src 目录,运行后输出的文件要放置在:../target 目录
3. 由于 dbdeploy 使用一个变更表保存所有的变更历史,因此需要指定这个表名,在这里使用的是 changelog
4. 其它参数比较简单,一看就明白。

创建好目录就可以运行了,我的目录结构如下:
/
    src/
        *.sql     --放置变更的脚本
    target/      -- 输出
    tools/
        Resources/
        dbdeploy.exe
        *.dll
        run.bat
        run.config.xml

三、运行
使用时,运行 run.bat 即可。一方面,它会将变更应用到本地数据库,另一方面,在 target/ 目录下生成 changes.sql, 可当作上线脚本。
第一运行时,报了一个错:"找不到 MysqlData.dll, version=1.0....", 这些数据库驱动是运行时动态加载的。需要将对应的驱动模块放到 tools 目录。从 mysql 官网下载 mysql-connector-net. 把 MysqlData.dll 拿过来,然后编辑 dbproviders.xml, 找到 mysql, 修改对应的内容为:
assemblyName="MySql.Data"

这么做是为了不受 MySqlData.dll 的版本影响,无论什么版本都能加载。

再次运行,没再报错。

四、实践
如何利用工具进行数据库变更管理?
1. 所有结构性变更,配置性变更都记录到脚本中。其中结构性变更位于 DDL.sql 中,配置性变更位于 DML.sql 中。
2. 为了能使用变更顺序地执行,特将变更文件名格式定为:yyyyMMddHHmmss_DML.sql. (DLL类似)
3. 创建辅助脚本,生成变更的文件。在本地创建 createDDLFile.bat 和 createDMLFile.bat. 内容如下:
createDDLFile.bat
---------------------------------------------------------
@echo off

set t=%Time%
if "%t:~0,1%" ==" " (
    set t=0%t:~1%
)
set NO=%Date:~0,4%%Date:~5,2%%Date:~8,2%%t:~0,2%%t:~3,2%%t:~6,2%

set filename=%no%_DDL.sql
set filepath="src\%filename%"

echo "" > %filepath%
echo New File: %filename%
---------------------------------------------------------

05-06 23:44