利用kettle的JS进行ETL数据校验(升级版)

简介: 无意中在网上看到一篇文章《利用kettle中的JS来完成ETL数据校验》,挺受启发的,觉得用JS来实现ETL的自动化校验,是个不错的思路。但是这篇文章里给的JS脚本样例确实有待改进,一是让初学者看着不那么清晰,二是扩展性和维护性都较差。于是我做了二次改造,重新编写了脚本
版权声明:本文为博主原创文章,未经博主允许不得转载。欢迎访问我的博客 https://blog.csdn.net/smooth00/article/details/79195506

       无意中在网上看到一篇文章《利用kettle中的JS来完成ETL数据校验》,挺受启发的,觉得用JS来实现ETL的自动化校验,是个不错的思路。但是这篇文章里给的JS脚本样例确实有待改进,一是让初学者看着不那么清晰,二是扩展性和维护性都较差。于是我做了二次改造,重新编写了脚本,如下:

//Script here
var strConn = "TestOrcl";
var check_status=0;//如果检测到有任何一种校验错误,则check_status=1
var check_table="E_OT_PRMTALT";//校验有关的表名字
var check_table_id="LICALTID";//校验表主键
var check_name=LICALTID;//校验表主键值
var check_detail="";//校验到的错误详细情况
var check_type="";//校验到的错误类型
var check_date=new Date();//校验时间
var source_table="E_OT_PRMTALT";//数据源表名称,如果数据来自多个数据表,则需要声明多个
var source_table_id="LICALTID";//数据源表主键,如果多个表联合主键,则需要声明多个主键

/////////////////////////////字段唯一性校验//////////////////////////////////////////
var isuniqueArray=new Array("LICALTID","LICID");//一维数组,表的字段名
var isunique_str="";
var isunique_column="";
for(var i=0;i<isuniqueArray.length;i++){
//1:唯一性枚举值
  isunique_str+="var "+isuniqueArray[i]+"_isunique=0;";
  //唯一性校验枚举值赋值
  isunique_str+="var uniquesql_"+isuniqueArray[i]+"=\"SELECT count(1) FROM "+check_table+" where "+isuniqueArray[i]+"='\"+"+isuniqueArray[i]+"+\"' \";";
  isunique_str+="if(fireToDB(strConn,uniquesql_"+isuniqueArray[i]+")[0][0]==1){"+isuniqueArray[i]+"_isunique=1;}";
  //校验所有表需要校验的字段,如果有一个校验失败,则校验状态为1
  isunique_str+="if(check_status==0){if("+isuniqueArray[i]+"_isunique==0)check_status=1;}";
  //check is unique? return not unique column
  isunique_str+="if("+isuniqueArray[i]+"_isunique==0){if(isunique_column==\"\"){ isunique_column = \""+ isuniqueArray[i] +"\";}else{isunique_column+=\"、\"+\""+isuniqueArray[i]+"\";}}"; 
}
//最终输出的错误详细情况
isunique_str+="if(check_status==1){check_type=\"违反唯一规则\";check_detail=\"表\"+source_table+\"中,字段\"+isunique_column+\"违反了唯一规则\";}";
eval(isunique_str);

//////////////////////////////////////////////////////////////////////////////////
/////////////////////////////字段非空校验//////////////////////////////////////////
var isnullArray=new Array("ALT","ALTBE","ALTAF","ALTDATE");//一维数组,表的字段名
var isnull_str="";
var isnull_column="";
check_status=0;//校验状态置0
for(var i=0;i<isnullArray.length;i++){
	//2:非空枚举值
	isnull_str+="var "+isnullArray[i]+"_isnull=0;";
	//非空校验枚举值赋值
	isnull_str+="if("+isnullArray[i]+"==null||"+isnullArray[i]+"==\"\"){"+isnullArray[i]+"_isnull=1;}";
	//校验所有表需要校验的字段,如果有一个校验失败,则校验状态为1
	isnull_str+="if(check_status==0){if("+isnullArray[i]+"_isnull==1)check_status=1;}";
	//check is null? return null column
	isnull_str += "if("+isnullArray[i]+"_isnull==1){if(isnull_column==\"\"){isnull_column = \""+ isnullArray[i] +"\";}else{isnull_column+=\"、\"+\""+isnullArray[i]+"\";}}";
}
//最终输出的错误详细情况
isnull_str+="if(check_status==1){if(check_detail==\"\"){check_type=\"违反非空规则\";check_detail=\"字段\"+ isnull_column +\"违反了非空规则\";}else{check_type+=\",\"+\"违反非空规则\";check_detail+=\",字段\"+ isnull_column +\"违反了非空规则\";}}";
eval(isnull_str);

//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////标准值校验//////////////////////////////////////////
var isnormalArray = [["S_EXT_FROMNODE","in ('220000')"],["ALT","in ('许可文件编号','许可文件名称','许可机关','许可内容')"]];//二维数组,第一列为字段,第二列为匹配规则
var isnormal_str="";
var isnormal_column="";
check_status=0;//校验状态置0
for(var i=0;i<isnormalArray.length;i++){
	//3:标准化枚举值
	isnormal_str+="var "+isnormalArray[i][0]+"_isnormal=0;";
	//标准化校验枚举值赋值
	isnormal_str+="var normalsql_"+isnormalArray[i][0]+"= \"select  count(1) from "+check_table+" where "+ isnormalArray[i][0] +" "+isnormalArray[i][1]+" and "+check_table_id+"='"+check_name+"'\";";
	isnormal_str+="if(fireToDB(strConn, normalsql_"+isnormalArray[i][0]+")[0][0]>0){"+ isnormalArray[i][0] +"_isnormal=1;}";
	//校验所有表需要校验的字段,如果有一个校验失败,则校验状态为1
	isnormal_str+="if(check_status==0){if("+isnormalArray[i][0]+"_isnormal==0) check_status=1;}";
	//check is normal? return not normal column
	isnormal_str+="if("+isnormalArray[i][0]+"_isnormal==0){if(isnormal_column==\"\"){ isnormal_column = \""+ isnormalArray[i][0] +"\";}else{isnormal_column+=\"、\"+\""+isnormalArray[i][0]+"\";}}";
}
//最终输出的错误详细情况
isnormal_str+="if(check_status==1){if(check_detail==\"\"){check_type=\"违反标准化规则\";check_detail=\"字段\"+ isnormal_column +\"违反了标准化规则\";}else{check_type+=\",\"+\"违反标准化规则\";check_detail+=\",字段\"+ isnormal_column +\"违反了标准化规则\";}}";
eval(isnormal_str);
//////////////////////////////数据类型校验//////////////////////////////////////////
var datatypeArray = [["ALTDATE","isDate"],["ALTAF","isNum"]];//二维数组,第一列为要校验的数据字段,第二列为数据类型校验函数(isDate[日期]、isNum[数字]、isMailValid[邮箱]、isEmpty[空])
var datatype_str="";
var datatype_column="";
check_status=0;//校验状态置0
for(var i=0;i<datatypeArray.length;i++){
	//4:类型校验枚举值
	datatype_str+="var "+datatypeArray[i][0]+"_datatype=0;"; 
	//数据类型校验枚举值赋值
	datatype_str+="var datatypesql_"+datatypeArray[i][0]+"=\"select "+datatypeArray[i][0]+" from "+ check_table +" where "+check_table_id+"='"+check_name+"'\";";
	datatype_str+="if("+datatypeArray[i][1]+"(fireToDB(strConn,datatypesql_"+datatypeArray[i][0]+")[0][0])) "+ datatypeArray[i][0]+"_datatype=1;";
	//校验所有需要校验的字段,如果有一个校验失败,则校验状态为1
	datatype_str+="if(check_status==0){if("+datatypeArray[i][0]+"_datatype==0) check_status=1;}";
	//check is datatype? return not datatype column
	datatype_str+="if("+datatypeArray[i][0]+"_datatype==0){if(datatype_column==\"\"){ datatype_column =\""+datatypeArray[i][0]+"\";}else{datatype_column+=\"、"+datatypeArray[i][0]+"\";}}";
}
//最终输出的错误详细情况
datatype_str+="if(check_status==1){if(check_detail==\"\"){check_type=\"违反数据类型规则\";check_detail=\"字段\"+datatype_column+\"违反数据类型规则\";}else{check_type+=\",\"+\"违反数据类型规则\";check_detail+=\",字段\"+datatype_column+\"违反数据类型规则\";}}";
eval(datatype_str);
//////////////////////////////////////////////////////////////////////////////////////
if(check_detail!="")
{
check_detail=check_detail+","+source_table_id+"="+check_name;
}

以下是执行后的效果:


在此基础上我们还可以扩展更多的校验,比如通过正则表达式的方式(利用kettle的isRegExp函数),如下:

//////////////////////////////正则表达式校验//////////////////////////////////////////
var dataArray = [["Email","^\\w+@[a-zA-Z_]+?\\.[a-zA-Z]{2,3}$","^[\\w-\.]+@([\\w-]+\\.)+[\\w-]{2,4}$"]];//二维数组,第一列为要校验的数据字段,第二列为规则1,第三列为规则2(可选)
var data_str="";
var data_column="";
check_status=0;//校验状态置0
for(var i=0;i<dataArray.length;i++){
	//4:类型校验枚举值
	data_str+="var "+dataArray[i][0]+"_data=0;"; 
	//数据类型校验枚举值赋值
	data_str+="var datasql_"+dataArray[i][0]+"=\"select "+dataArray[i][0]+" from "+check_table+" where "+ check_table_id +"='"+check_name+"'\";";
	data_str+="if(isRegExp(fireToDB(strConn,datasql_"+dataArray[i][0]+")[0][0],dataArray[i][1],dataArray[i][2] )>-1) "+dataArray[i][0]+"_data=1;";
	//校验所有需要校验的字段,如果有一个校验失败,则校验状态为1
	data_str+="if(check_status==0){if("+dataArray[i][0]+"_data==0) check_status=1;}";
	//check is data? return not data column
	data_str+="if("+dataArray[i][0]+"_data==0){if(data_column==\"\"){data_column=\""+ dataArray[i][0] + "\"; } else {data_column+=\"、"+dataArray[i][0]+"\";}}";
}
//最终输出的错误详细情况
data_str+="if(check_status==1){if(check_detail==\"\"){check_type=\"违反数据类型规则\";check_detail=\"字段\"+ data_column +\"违反数据类型规则\";}else{check_type+=\",\"+\"违反数据类型规则\";check_detail+=\",字段\"+ data_column + \"违反数据类型规则\";}}";eval(data_str);
以上脚本的好处就是,可以直接通过修改变量,就能对不同输出表的不同字段进行校验,基本上不用修改逻辑代码,如果进一步优化一下,就可以写成函数,直接调用。可以把检验字段和检验规则进一步参数化,通过调用参数表,来执行数据驱动的校验测试(这就是一种自动化测试的思路)。

目录
相关文章
|
27天前
|
JavaScript 测试技术 API
跟随通义灵码一步步升级vue2(js)项目到vue3版本
Vue 3 相较于 Vue 2 在性能、特性和开发体验上都有显著提升。本文介绍了如何利用通义灵码逐步将 Vue 2 项目升级到 Vue 3,包括备份项目、了解新特性、选择升级方式、升级依赖、迁移组件和全局 API、调整测试代码等步骤,并提供了注意事项和常见问题的解决方案。
|
2月前
|
移动开发 前端开发 JavaScript
JS配合canvas实现贪吃蛇小游戏_升级_丝滑版本_支持PC端和移动端
本文介绍了一个使用JavaScript和HTML5 Canvas API实现的贪吃蛇游戏的升级版本,该版本支持PC端和移动端,提供了丝滑的转向效果,并允许玩家通过键盘或触摸屏控制蛇的移动。代码中包含了详细的注释,解释了游戏逻辑、食物生成、得分机制以及如何响应不同的输入设备。
58 1
JS配合canvas实现贪吃蛇小游戏_升级_丝滑版本_支持PC端和移动端
|
6月前
|
JavaScript 前端开发 Java
kettle开发篇-JavaScript脚本
kettle开发篇-JavaScript脚本
297 0
|
6月前
|
JavaScript
【升级玩法】js用push、unshift、shift、pop或splice实现5张卡片(可以自由定义更多)轮播图效果banner、swiper
【升级玩法】js用push、unshift、shift、pop或splice实现5张卡片(可以自由定义更多)轮播图效果banner、swiper
|
11月前
|
SQL JavaScript 前端开发
Kettle使用JavaScript代码处理数据
Kettle使用JavaScript代码处理数据
199 0
|
运维 监控 JavaScript
Node.js躬行记(22)——Node环境升级日志
Node.js躬行记(22)——Node环境升级日志
从零开始手把手教你使用javascript+canvas开发一个塔防游戏07塔的升级和出售
从零开始手把手教你使用javascript+canvas开发一个塔防游戏07塔的升级和出售
111 0
|
前端开发 JavaScript 应用服务中间件
Vue 2.x折腾记 - (14) Nuxt.js 2 正式版升级采坑以及部署姿势改动
记录下过程遇到的一些问题及修正知识; 之前用的nuxt 1.4, 仅做备忘录,有兴趣瞧瞧,没兴趣止步;
474 0
Node.js躬行记(17)——UmiJS版本升级
  在2020年我刚到公司的时候,公司使用的版本还是1.0,之后为了引入微前端,迫不得已被动升级。
|
缓存 JavaScript
关于升级最新版本node.js你知道多少?
关于升级最新版本node.js你知道多少?