Kettle7.0实现主键,索引迁移

时间:2022-11-10 14:18:43

之前的博客提到过,kettle的数据抽取主要在于抽取数据,而没有考虑数据库的函数、存储过程、视图、表结构以及索引、约束等,但这些对于数据库来说又是至关重要的,所以我们需要通过修改源码的方式来实现。

具体实现方式为:扩展kettle向导中的多表复制菜单里的功能,在该功能创建的作业中添加节点用于添加输出表的主键和索引。

一、Kettle源码下载

目前我使用的是kettle7.0.0版本,下载的源码版本要与之对应,git下载地址:

https://github.com/pentaho/pentaho-kettle/tree/7.0.0.0-R

在master下选择tags选项卡,选取自己需要的版本:
Kettle7.0实现主键,索引迁移

现在我们拥有了发行版kettle工具和对应的源码,就可以开始进行修改了。

二、Kettle源码运行

1.创建java项目

新建java项目并在项目根目录下建立core,dbdialog,engine,ui,plugins,lib文件夹。
Kettle7.0实现主键,索引迁移
分别将源码目录下的代码拷贝到对应的项目文件下:

Kettle7.0实现主键,索引迁移
拷贝之后各个文件内容如下:
Core,engine,ui,dialog文件内容:
Kettle7.0实现主键,索引迁移
plugins文件内容:
Kettle7.0实现主键,索引迁移
将发行版kettle工具免安装包的lib,libswt,launcher,simple-jndi 四个文件夹拷贝至java项目的根目录,全部拷贝完成后,当前项目根目录下有这些文件:
Kettle7.0实现主键,索引迁移
然后删除lib下的这3个jar包:
Kettle7.0实现主键,索引迁移
选择项目,右键——》Build Path——》Add Libraries——》next——》User Libraries——》New,新建一个library——》选中新建立的library,点击Add JARS——》选中项目下lib目录下的所有jar,以及根据自己电脑型号选择对应的libswt下的swt.jar,点击OK。
比如我的电脑是64位的,就选择win64:
Kettle7.0实现主键,索引迁移
然后选择core、dbdialog、engine、ui四个目录,右键——》Build Path——》Use as Source Folder。
Kettle7.0实现主键,索引迁移
测试是否配置成功,需要找到ui/org/pentaho/di/ui/spoon/Spoon.java,右键运行即可,若出现程序界面,表示配置成功。

三、Kettle源码修改

找到项目目录下的ui/org/pentaho/di/ui/spoon/delegates/SpoonJobDelegate.java方法,这个就是我们主要需要修改的地方。

首先要在这个类的包下面加个工具类用来实现对索引和约束的迁移,工具类代码的git地址如下:

https://gist.github.com/javachen/1564353

修改SpoonJobDelegate.java,在ripDB方法里面添加如下代码(在大约750行左右添加):

Class.forName("com.mysql.jdbc.Driver");
Class.forName("oracle.jdbc.driver.OracleDriver");
String sourceMsg = sourceDbInfo.getHostname() + ":" + sourceDbInfo.getDatabasePortNumberString() + ":" + sourceDbInfo.getDatabaseName();
String targetMsg = targetDbInfo.getHostname() + ":" + targetDbInfo.getDatabasePortNumberString() + "/" + targetDbInfo.getDatabaseName();
Connection sourceCon = DriverManager.getConnection(
                    "jdbc:oracle:thin:@" + sourceMsg, sourceDbInfo.getUsername(), sourceDbInfo.getPassword());
Connection targetCon = DriverManager.getConnection(
                    "jdbc:mysql://" + targetMsg, targetDbInfo.getUsername(), targetDbInfo.getPassword());

String pksql = SpoonUtil.exportPkAndIndex(
                    sourceDbInfo, sourceCon, tables[i],
                    targetDbInfo, targetCon, tables[i]);
if (!Const.isEmpty(pksql)) {
location.x += 300;
    JobEntrySQL jesql = new JobEntrySQL(BaseMessages.getString(PKG,"Spoon.RipDB.AddPkAndIndex")
                        + tables[i] + "]");
    jesql.setDatabase(targetDbInfo);
    jesql.setSQL(pksql);
    jesql.setDescription(BaseMessages.getString(PKG,
    "Spoon.RipDB.AddPkAndIndex")
    + tables[i]
    + "]");
    JobEntryCopy jecsql = new JobEntryCopy();
    jecsql.setEntry(jesql);
jecsql.setLocation(new Point(location.x, location.y));
    jecsql.setDrawn();
    jobMeta.addJobEntry(jecsql);
    // Add the hop too...
    JobHopMeta jhi = new JobHopMeta(previous, jecsql);
    jobMeta.addJobHop(jhi);
    previous = jecsql;
}

由于需求就是要把oracle数据库迁移到mysql,我的连接信息直接写死了,如果想灵活获取,也可以自行修改。

修改完成后最好clean一下再运行程序,之前我没有clean,报了找不到文件之类的错误,排查了半天才发现clean一下就解决了······

四、Kettle使用

按照上一篇Kettle文档中的操作,新建Job后建立oracle和mysql的数据库连接,配置mysql的编码,之后选择源数据库和目标数据库,选择需要导入的表,最后输入对应的job名称和存储位置即可生成最新的job:
Kettle7.0实现主键,索引迁移

可以看出,相对于修改之前Job,修改源码之后多出了中间添加主键和索引约束步骤,执行当前Job,就可以将oracle中的主键和索引迁移到mysql了。

本博客参考了以下博客,里面还提到了插件相关的操作:
http://www.zuidaima.com/blog/3670924901010432.htm