设计 Data Migration DSL
0x00
首先简单解释一下「Data Migration」和「DSL」。
Data Migration 是一种对数据进行选择,准备,抽取和转换操作的系列流程,最终结果是,旧系统的数据被迁移到不同数据结构的新系统上。
DSL (Domain Specific Language) 则是一种面向特定领域的语言,例如在解决 Gradle 配置这个问题域中,就现在分别有基于 Groovy 和 Kotlin 的两套不同 DSL。
0x01
前段时间,一个替换旧系统的项目就面临了 Data Migration 的需求。其实团队之前就已经有过几次类似的经验了,面临的根本问题都是:
- 新旧两套系统的数据设计完全不同,业务流程也有差异
- 旧系统的数据库数据不能直接暴露,只能在用户界面上导出 Excel
而基于上面的条件限制,想简单地通过数据库进行 Migration 并不可能实现。所以,已有的解决方案是根据每次 Migration 的业务要求,来编写 Migration Script,再将多处调用的方法提取到 Common Module。
但是这样的实践,即使复用了部分的逻辑,不同的开发依然会写出风格各异的 Migration Script。这也意味着后面每做一轮新的 Migration,就会有一套新的轮子。
为了解决这个 特定的问题域,便设计了一套 新的轮子 「Data Migration DSL」。
0x02
先鸟瞰整个 Migration Script,把它当作一个 Function:
migration excel +----------------------+
---------------------->| | migrated sql
| Migration script |---------------->
---------------------->| | logging file
mapping configuration +----------------------+
简化了 Migration 的实际需求,只会关注到一些关键信息
与之对应的输入是:
migration excel
是旧系统导出的 Excel 数据mapping configuration
是两套系统的中各类 Dropdown 的映射配置- 省略了其他的配置信息
输出是:
migrated sql
是需要插入到新系统的 SQL 文件logging file
主要记录程序的运行记录,包括 Data Clean, Data Validation 以及其他流程的记录信息- 省略了其他生成的信息
0x03
往这个 Function 中走进一些:
+-------------+
| | migrated sql
| Output |---------------->
| |
+-------------+
^
+-----------+ +--------------------------------+ |
migration excel | | pipe | |------------------+
---------------------->| Input |--------->| Models (with dependencies) | migrated result
mapping configuration | | | |------------------+
+-----------+ +--------------------------------+ |
v
+-------------+
| | logging file
| Logging |---------------->
| |
+-------------+
内部由以下四个模块来实现 Migration 流程:
Input
处理输入的数据- 将定义好格式的 mapping configuration 读到内存中,例如
Key/Value
的形式 - 根据导入的 Excel 的结构,重新组织数据结构,并重定向到到下一步的
Models
模块中
- 将定义好格式的 mapping configuration 读到内存中,例如
Models
定义新系统的业务模型,会由多个Model
构成- 每个
Model
会定义多个property
来表示相应业务模型的字段信息 - 每个
property
分别定义有取值,验证,转换等操作 - 此外,多个
property
之间可能存在值引用,关联计算等依赖关系,这也是需要进行声明的 - 从上一个模块传来的旧系统数据,便会通过上面的定义转换成新系统的业务模型,并重定向到
Output
和Logging
中
- 每个
Output
将migrated result
转换成具体的数据库和表上的 SQL 语句Logging
统计migrated result
的概要和程序运行时的记录
从上述模块的描述中,不难看出在整个 Data Migration DSL 中 Models
是新旧系统数据转换中最重要的一部分。同时这部分的复杂度也是和新系统的业务复杂度紧密相关的,无论采取何种实现方式都是无法消除的,只能尽量去减少。
后面将会基于以上设计和想法,实现这个 Data Migration DSL 的 Demo