0.前言
两个数据库表之间使用日期(Date或timestamp)字段进行增量同步,是ETL操作的基本操作(本文举例的源表数据只新增不删除不修改的情况),最简单的步骤如下:
- 获取目标表时间戳字段的max值;
- 获取源表时间戳字段的max值;
- 比较确认源表的时间要大于目标表,否则同步没有意义;
- 根据目标表的时间戳字段获取源表的数据并写入至目标表;
1.主作业
主作业工作流如下图所示,这里使用变量的方式进行日期字段的传递。
以下逐个组件进行说明:
1.1 设置变量
这里将源表、目标表的最大时间戳字段先申明为变量:TARGET_MAX_DATE、SOURCE_MAX_DATE,注意变量的有效范围。
1.2 获取目标表的最大日期
-
这个转换只有两个组件,从“表输入”组件获取目标表的最大时间戳,但这里要注意
日期格式
的转换。
-
表输入的SQL语句如下,我目标表是MySQL:
SELECT DATE_FORMAT(max(RUN_DATE), '%Y-%m-%d %H:%i:%s.%f') as target_max_month
FROM sasrep.rp_xxx
- “设置变量”组件的配置比较简单,如下图:
1.3 获取源表的最大日期
- 这个转换的设置与上述“获取源表的最大日期”的转换没有什么大的差别,但我源表是DB2,取数的SQL如下:
SELECT VARCHAR_FORMAT(max(RUN_DATE), 'YYYY-MM-DD HH24:MI:SS.FF6') as source_max_month
FROM SAS.rp_xxx
- “设置变量”的组件配置如下图:
1.4 写日志-变量赋值检查
- 在设置好变量后,这里通过写日志的方式做一个简单的检查,看变量是设置成功,因为我本人因为变量名拼写问题,老是没有设置变量成功,故将写日志作为调试的手段之一,日志的设置如下图所示:
1.5 日期比较
- 这里使用了javascript脚本来检查目标表的max日期是表比源表max日期要小,这里要注意kettle的js脚本返回结果是布尔类型的,完整javascript代码如下所示:
var target_max_date = parent_job.getVariable("TARGET_MAX_DATE");
var source_max_date = parent_job.getVariable("SOURCE_MAX_DATE");
target_max_date < source_max_date ;
上述返回结果的条件为true则正常数据同步,如果为false则中止同步。
1.6 增量读取原表记录并写目标表
-
这个转换只有“表输入”、“表输出”两个组件,以下是表输入组件的设置:
-
以下是表输出组件的设置,建议将批量提交的记录调大一些
1.7 写日志-日期比较结果
如果在“日期比较”节点的结果为false,再通过节点写日志,没这个节点问题也不大。
2.总结
以上就是通过日期字段进行增量同步的简单kettle工作流,但实际生产会比较复杂,注意事项如下:
- 上述只适用源表只新增无删除无更改的情况,且在同步作业时不会新增数据,生产时,最好回写“已读取”的标志;
- 由于通过日期获取源表数据时,日期的format是固定的,获取max日期时注意转换合适的字符串;