使用kettle进行problem表迁移
写在前面
目前本人正在学习使用kettle将从原数据库的信息迁移到新数据库,本博客仅为本人在学习过程的一些记录,不一定具有参考价值。
迁移过程主要任务内容
- 原数据库的problems表中的的题目描述、输入描述、输出描述、样例输入、样例输出等信息以
json
字符串格式存储在description
字段当中,需要解析该字段以获得相应信息; - 原数据库的problems表的
difficulty
字段代表着题目的难度,数值越大代表题目难度越大,与新数据库的problems表的value
字段的功能几乎一致,但difficulty
从0开始,value
从1开始,需要进行简单的转换; - 在题目描述、输入描述、输出描述、样例输入、样例输出等信息中,含有大量的html格式文本,需要将其转换成纯文本。
转换详细过程
转换流程图
先上图,灰色路径为调试用流程,请忽略。
流程如图:
- 连接原数据库,获得problems表内容;
- 解析
description
字段中的json
格式字符串,获得题目描述、输入描述、输出描述、样例输入、样例输出等信息; - 使用JS脚本将
difficulty
字段数值都加上1,与新数据的problems表的value
字段相对应; - 使用脚本将html格式文本转换为纯文本;
- 将新数据库中一些不能为空的字段填上默认内容;
- 将转换好的内容写入到新数据库的problems表中。
连接原数据库的problems表
在这里我们使用“表输入”组件。双击组件打开该组件的设置。
建立数据库连接
在“表输入”组件设置界面上面的“数据库连接”选项中选择相应的数据库连接。若没有建立数据库连接,选择“新建…”按钮创建新的数据库连接。
由于在该次迁移过程中我们使用MySQL数据库,因此连接类型选择“MySQL”,连接方式选择“Native(JDBC)”,在右方填上主机名称、数据库名称、端口号、用户名、密码,当然别忘了在上方填上连接名称。
信息填好之后,点击“测试”按钮可以确认能否正确连接上数据库。当显示下图信息说明能够连接上数据库了。
测试通过之后,点击确认,保存数据库连接信息。
若我们想修改已有的数据库连接信息,在“表输入”组件设置中选择“编辑…”按钮修改。
获取相应的内容
建立好数据库连接之后,我们需要使用SQL查询语句从数据库获取我们想要的信息。
我们可以使用kettle“获取SQL查询语句…”功能,自动生成SQL查询语句,也可以手动输入。
输出SQL查询语句后,点击“预览”功能可以查看从数据库获得的内容。
解析JSON串
JSON是一种结构简单的数据格式,被广泛使用。我们可以根据路径,获得一个JSON串内我们想要的信息。
我们使用“JSON input”组件,解析problems表的description字段内的信息。
双击组件打开组件设置,勾选“源定义在一个字段里”选项,“从字段获取源”选择description字段。
接着我们进入到“字段”设置页面,使用路径获得JSON存储的内容,为内容取个名称,选择数据类型。
JSON路径详细说起来挺多门道的,在这里我仅仅简述一下这次用到的 $
和 .
。
$
符号指代当前的整个JSON对象,.
当前的下一级内容。
以$.input
为例,在我们这次解析过程中,$
指代了当前整个JSON对象description
,$.input
指的是description
中下一级的input
字段。假设input
内有一个字段叫a
,我们可以使用路径$.input.a
访问。
处理difficulty
原problems表的difficulty
与新problems表的value
的区别仅仅在于基础数值不一样,在这里我的做法是给difficulty
所有记录的数值都加上1,使用“JavaScript代码”组件完成。
JavaScript代码比较简单,直接上图。下面“字段”表格要填上字段名称和类型。
“替换‘Fieldname’或‘Rename to’值”,若选择“是”,则替换原来已存在的相应字段;若选择“否”,则会生成一个新的字段。
将HTML格式文本转换为纯文本
这个是个十分常见的问题,一般来说,有两种常见的解决办法。
抄作业
https://www.jb51.net/article/184685.htm
这篇文章里给出了较好的解决方案。在kettle中使用“Java代码”组件,核心代码复制粘贴上去即可。
该代码即使在字符串中间出现换行也能处理掉HTML格式文本,经测试效果不错。
该代码引入的依赖jar包,kettle不一定自带,需要自行下载jar包,然后放入kettle所在文件夹中的lib
子文件夹中。
kettle的Java脚本相比较JS脚本来说使用起来要稍微麻烦一些,需要从流中获取信息内容,以及将处理后的内容写入到流中。但是kettle提供了大量的函数模板,总体来说使用体验不比JS脚本差多少。
自己手写
HTML格式文本转换为纯文本实际上是一个字符串替换问题。当处理的文本较为简单的时候,自己手写未尝不是一种好办法。
而在字符串替换中,常常会用到正则表达式。为此,我简单学习了一下正则表达式的内容,写了一个JS脚本,能够处理掉部分html标签,以及 
、&
等转义字符。
由于在本次迁移过程中需要处理的HTML格式文本较为复杂,该JS脚本并没有取得很好的效果,我最终还是选择了“抄作业”。毕竟大牛们实现的库函数,与一个人花费一两天实现的脚本,所花费的时间与精力以及考虑到的细节,根本不是一个级别的。
为不能为空的字段填充默认内容
在新problems表中,样例输入、样例输出、source、题目描述字段的内容不能为空,但我们发现在旧problems表中,不少记录的这些字段的内容为空,因此,我们使用“JavaScipt代码”组件填充一些默认内容。
JS脚本代码内容如下。
将转换后的信息写入到新数据库的problems表中
在这里,我们用到“表输出”组件。
双击组件打开组件设置,选择好数据库连接(建立数据库连接可以参数上文“连接原数据库的problems表”的“建立数据库连接”部分)。接着点击“目标表”选项后面的“浏览…”按钮,选择相应的表。在这里我们选择problems表。
接下来我们勾选“指定数据库字段”选项,然后选择“数据库字段”设置页面,点击“获取字段”,点击“输入字段映射”,将当前的数据流的字段映射到新数据库problems表中的相应字段,点击“确定”保存。
开始转换
接着我们保存这个转换,点击组件编辑区左上方“运行转换这个按钮”,等待转换完成即可。若日志出现ERROR提醒,则根据提醒修改相应错误,然后重新运行。
至此,problems表迁移完成。