Extract-Transform-Load,ETL,使用scriptella实现数据抽取同步
官方网站:http://scriptella.javaforge.com/
许可证:Apache License, Version 2.0
当前版本:Scriptella 1.0 Released (May 5, 2010)
最新版本:Scriptella 1.2 Released (2019)
系统需求:JRE 5.0+ (有些driver要求更高JRE,如JSR 223,要JRE6)
JRE 8
典型应用:(官方资料的简译)
执行 SQL,JS,JEXL,Velocity等脚本。
数据库迁移。LDAP,JDBC,XML等数据源的协作。
跨DB的ETL操作,以CSV,文本,XML等格式的导入导出。
作为Ant的一个task。* Db Schema 的自动升级。
官方文档:
略读,快速入门:http://scriptella.javaforge.com/tutorial.html
细读,常见问题:http://scriptella.javaforge.com/faq.html
研究,参考手册:http://scriptella.javaforge.com/reference/index.html
理解,API 文档:http://scriptella.javaforge.com/docs/api/index.html
了解,HOWTOs: 这个目前有两个,看看即可。
即用即查,驱动帝国:http://scriptella.javaforge.com/reference/drivers.html
Scriptella github 地址 https://github.com/scriptella
以下示例都是官方网站中比较有代表性的。
这里只是进行了简单的集中和部分注释。
官方地址 http://scriptella.javaforge.com/docs/api/scriptella/driver/script/package-summary.html
The following query executes a child script 10 times. As the result of
execution 10 records are inserted into a database table.
Additionally a log file log.txt is produced.
简译:下面的Query执行了10次内嵌Script。
效果是,在DB中插入了10条记录,并产生日志log.txt。
< xml> 完整的ETL文件
<?xml version="1.0" encoding="UTF-8"?> <!-- 指定编码,防止系统弄错字符集 -->
<!DOCTYPE etl SYSTEM "http://scriptella.javaforge.com/dtd/etl.dtd">
<etl>
<connection id="script" driver="script"/>
<connection id="out" driver="oracle" url="jdbc:oracle:thin:@localhost:1521:DB"/>
<connection id="log" driver="script" url="log.txt"/>
<query connection-id="script">
<![CDATA[
for (var i = 0; i < 10; i++) {
login = 'login' + i;
//You can instantiate Java objects and invoke static methods
var now = new java.sql.Timestamp(java.lang.System.currentTimeMillis());
query.next(); //Executes a child script element // * 执行后续的所有元素
}]]>
<!-- Inserts a parameterized row into a database -->
<script connection-id="out">
INSERT INTO Table(ID, Login, Login_Time) VALUES (?i, ?login, ?now);
</script>
<!-- Logs the message using MessageFormat class and parent context variables -->
<script connection-id="log">
// create Java String array of 2 elements
var a = java.lang.reflect.Array.newInstance(java.lang.Object, 2)
a[0] = now;a[1] = i;
println(format.format(a));
</script>
</query>
</etl>
官方地址 http://scriptella.javaforge.com/docs/api/scriptella/driver/csv/package-summary.html
< xml > ETL文件片段
<connection id="in" driver="csv" url="data.csv" />
<connection id="out" driver="csv" url="report.csv">
#Use empty quote to turn off quoting
quote=
separator=;
</connection>
<!-- connection里面可以设置参数,各个connection不一样 -->
<script connection-id="out">
ID,Priority,Summary,Status
</script>
<query connection-id="in">
<!--Empty query means select all-->
<script connection-id="out">
$rownum,$priority,$summary,$status
</script>
</query>
< txt> data.csv
priority,summary,status
11,summary1,21
12,summary1,22
< txt> report.csv
ID;Priority;Summary;Status
1;11;summary1;21
2;12;summary1;22
解说:
$priority,$summary,$status,
就是CVS的头(首行) priority,summary,status
。
官方地址 http://scriptella.javaforge.com/docs/api/scriptella/driver/text/package-summary.html
大部分时候,我们处理文本,用到Text Driver,然后用正则表达式匹配行划分组。示例比较简单。
官方地址 http://scriptella.javaforge.com/docs/api/scriptella/driver/mail/package-summary.html
< xml> HTML邮件
<etl>
<connection driver="mail" url="mailto:user@nosuchhost.com?subject=Hello"
classpath="mail.jar:activation.jar">
type=html
mail.smtp.host=mail.host.name
mail.user=user
mail.password=password
mail.from=Firstname Lastname <user@nosuchhost.com>
</connection>
<script><![CDATA[
<html>
<body>
Hello,
<hr>
<a href="http://scriptella.javaforge.com/" title="Powered by Scriptella ETL">
<img src="http://scriptella.javaforge.com/images/scriptella-powered.gif"
width="88" height="31" border="0" alt="Powered by Scriptella ETL">
</a>
</body>
</html>]]>
</script>
</etl>
< xml> 动态发邮件
<etl>
<connection id="mail" driver="mail" url="mailto:$email?subject=Hello $name"
classpath="mail.jar:activation.jar">
mail.smtp.host=mail.host.name
mail.user=user
mail.password=password
mail.from=Administrator <user@nosuchhost.com>
</connection>
<connection id="db" .../>
<query connection-id="db" >
SELECT * FROM Users
<script connection-id="mail">
#$rownum
Message produced by Scriptella ETL
</script>
</query>
</etl>
官方地址
把 Excel当Db使用,因为是JDBC驱动。
< xml> ETL文件片段
<connection id="xls" url="jdbc:xls:file:report.xls" classpath="sqlsheet-0.1.0.jar; poi-3.0.2-FINAL-20080204.jar; jsqlparser.jar" />
<script connection-id="xls">
CREATE TABLE SHEET1(
COL1 INT,
COL2 INT
);
</script>
...
<query connection-id="db">
...
<script connection-id="xls">
INSERT INTO SHEET1 (COL1,COL2) VALUES(${rownum},${col2_value});
</script>
</query>
1、query
标签,只能用来查询数据,UPDATE,INSERT,DELETE
要用Script
。
2、if="priority == $priority"
,query/script
属性if
里变量的使用。
3、INSERT INTO $TABLE2 VALUES (?V1, ?{V2+V3})
变量的使用方法和作用。
4、变量的作用域是自身和子标签,父标签的同名变量被隐藏。