Kettle是一款ETL工具,Java编写,可实现有关数据的许多操作,全平台支持,可在Java代码中调用也可使用图形化工具调用。2014年使用过几个月,版本是4.x,可能与现在版本差别挺大。只使用过图形化界面的SPOON,并且是部署在Windows Server 2008中。
使用总结
- 在使用”Excel输入”时,Kettle会读取到表格有数据的最后一行,哪怕选择的字段不是最长的列,也会读到最长的列的最后一行,所以在输入时,如果选择的字段不是最长的列,会读取出一些<null>,解决办法是将需要输入的数据单独存在一个表格中,读取这个表格,避免其他列干扰。
- 数据库连接最好使用JNDI方式,SQL中的变量最好使用配置kettle.properties方式,第一次建立文件时,一定想清楚有哪些字段会变,设置为变量,省去后续再改的麻烦。
- 在”表输入”等地方写SQL语句时,一定加上别名,否则在诸如”表输出”的地方有字段选择时,修改了SQL的字段名,这些地方就得跟着改,加上别名后就避免了这个情况。
- 替换SQL中的字符或字符串可以使用MySQL自带的replace函数也可以使用“字符串替换”这个工具。
- 如果有选择、插入、更新、删除需要多表联合查询时,需使用脚本中的”执行SQL脚本”工具,在此工具中,可以获取前边步骤的输出字段当做变量,在语句中使用?代替变量,字符串型变量需要将问号加上单引号即’?’,也可以不加转而使用执行SQL脚本中的Quote Strings选择框代替,此功能的好处是可以避免数据中的特殊字符,而执行每一行选择框的意思是前边步骤有输出数据,输出一行此语句就执行一行,如果前边步骤没有输出,就不会执行语句。
- Kettle设置数据库的几种方式:
- 在转换中设置DB连接;
- 在kettle.properties中设置变量,然后在转换中设置DB连接,使用变量,此方法不能将密码设置成变量;
- 配置JNDI,在DB连接中使用JNDI方式。配置JNDI需要在安装目录\data-integration\simple-jndi\jdbc.properties中加入jdbc的连接信息,比如下面这个示例:
############ MYSQL ############ MYSQL/type=javax.sql.DataSource MYSQL/driver=com.mysql.jdbc.Driver MYSQL/url=jdbc:mysql://127.0.0.1:3309/testdb MYSQL/user=test MYSQL/password=test
- 关于使用Kettle从MySQL取时间数据写入Oracle的问题解决:
- 前提:MySQL为int型Unix时间戳,Oracle为DATE型时间
- 问题:使用Kettle表输入功能从MySQL读取时间使用FROM_UNIXTIME将时间戳转为YYYY-MM-DD HH24:MI:SS格式后通过表输出功能写入Oracle,提示ORA-01861: 文字与格式字符串不匹配。
- 问题分析:
- Oracle的默认日期格式并不是YYYY-MM-DD HH24:MI:SS
- FROM_UNIXTIME的结果是字符串,并不是DATE型
- 解决办法:
- 更改Oracle的参数文件中的NLS_DATE_FORMAT为YYYY-MM-DD HH24:MI:SS
- 将FROM_UNIXTIME的结果用STR_TO_DATE转为DATE型
避坑
在数据迁移时遇到一些坑,记录一下。
- 若遇到MySQL中VARCHAR或LONGTEXT类型的字段,需确认有无转义符”\“,因为有可能\“会被转义为”而被当成SQL语句外引号的末尾引号,\;会被转义为;当成SQL语句的结束,如果有,有两种解决办法:1.跳过这条数据,之后直接复制粘贴进去;2.将数据的转义符替换为特殊字符,写入完毕再将转义符替换回来。
- 若遇到MySQL中VARCHAR或LONGTEXT类型的字段,需确认有无特殊中文字符,有一些看起来像中文的字符在UTF8的编码下无法显示,所以无法写入,遇到这种情况,有几种解决办法:1.跳过这条数据,之后直接复制粘贴进去;2.在INSERT执行前先执行set names ‘utf8mb4’ (gbk好像也有效),此语句用来改变临时会话时客户端(即SQL语句)与服务器端的字符集编码格式,在连接断开后无效,遇到乱码INSERT不了的时候同样有效。
- 遇到MySQL的ENUM即枚举类型时,需确认所有存储数据是否都符合枚举类型值,有可能出现枚举值之外的值,此时需要转换。
- 遇到MySQL的数字值时,在Java中最好使用Integer、Double等可以赋NULL值的数据类型,在Kettle中需要使用替换NULL值的工具。