- 原文作者:water___Wang
- 原文标题:datax(27):不太常见配置项querySql、preSql、postSql、splitPk
- 原文地址:https://blog.csdn.net/WANTAWAY314/article/details/113505791
- 发布时间:2021-02-02 16:11:51
每个datax的json都有自己的json配置文档,基本大同小异,有几个配置较为少用,但是用了之后,真香~
目录
每个datax的json都有自己的json配置文档,基本大同小异,有几个配置较为少用,但是用了之后,真香~
目录
当用户配置querySql时,xxxReader直接忽略table、column、where条件的配置
。如果配置了querySql又配置了table,column、where等,在log中会有警告日志,具体代码在
OriginalConfPretreatmentUtil.dealColumnConf()
……
if (null != userConfiguredColumns && userConfiguredColumns.size() > 0) {
LOG.warn(
"您的配置有误. 由于您读取数据库表采用了querySql的方式, 所以您不需要再配置 column. 如果您不想看到这条提醒,请移除您源头表中配置中的 column.");
originalConfig.remove(Key.COLUMN);
}
// querySql模式,不希望配制 where,那样是混淆不清晰的
String where = originalConfig.getString(Key.WHERE, null);
if (StringUtils.isNotBlank(where)) {
LOG.warn(
"您的配置有误. 由于您读取数据库表采用了querySql的方式, 所以您不需要再配置 where. 如果您不想看到这条提醒,请移除您源头表中配置中的 where.");
originalConfig.remove(Key.WHERE);
}
// querySql模式,不希望配制 splitPk,那样是混淆不清晰的
String splitPk = originalConfig.getString(Key.SPLIT_PK, null);
if (StringUtils.isNotBlank(splitPk)) {
LOG.warn(
"您的配置有误. 由于您读取数据库表采用了querySql的方式, 所以您不需要再配置 splitPk. 如果您不想看到这条提醒,请移除您源头表中配置中的 splitPk.");
originalConfig.remove(Key.SPLIT_PK);
}
……
目前主要是reader插件,主要有rdbmsReader(sqlServer、mysql、postgresql、oracle等)、hbase20xsqlreader、DrdsReader和KingbaseesReader。
目前主要的代码都在CommonRdbmsReader的startRead()中
1. 获取 String querySql = readerSliceConfig.getString(Key.QUERY_SQL);
2. 调用 rs = DBUtil.query(conn, querySql, fetchSize);
DBUtil.query方法中最终实现是如下:
public static ResultSet query(Statement stmt, String sql)
throws SQLException {
return stmt.executeQuery(sql);
}
@table
表示,这样在实际执行 Sql 语句时,会对变量按照实际表名称进行替换。比如你的任务是要写入到目的端的100个同构分表(表名称为:datax_00,datax01, … datax_98,datax_99),并且你希望导入数据前,先对表中数据进行删除操作,那么你可以这样配置:"preSql":["delete from 表名"]
,效果是:在执行到每个表写入数据前,会先执行对应的 delete from 对应表名称目前主要是writer插件,主要有rdbmsWriter、mongoDBWriter、AdsWriter等。
一般在writer的prepare阶段,例如CommonRdbmsWriter.prepare()方法
1.获取所有preSqls
List<String> preSqls = originalConfig.getList(Key.PRE_SQL, String.class);
List<String> renderedPreSqls = WriterUtil.renderPreOrPostSqls(preSqls, table);
2.执行preSqls
WriterUtil.executeSqls(conn, renderedPreSqls, jdbcUrl, dataBaseType);
大部分的writer插件
同preSql,不在赘述;
推荐splitPk用户使用表主键,因为表主键通常情况下比较均匀,因此切分出来的分片也不容易出现数据热点。
目前splitPk仅支持整形数据切分,不支持浮点、字符串、日期等其他类型
。如果用户指定其他非支持类型,MysqlReader将报错!
如果splitPk不填写,包括不提供splitPk或者splitPk值为空,DataX视作使用单通道同步该表数据。
目前主要是reader插件,主要有rdbmsReader(sqlServer、mysql、postgresql、oracle等)、hbase20xsqlreader、DrdsReader和KingbaseesReader。
主要在各类reader插件中,以CommonRdbmsReader为例,在CommonRdbmsReader.preCheck()中
1、从配置获取splitPK
String splitPK = queryConf.getString(Key.SPLIT_PK);
2、构造出PreCheckTask 对象
PreCheckTask t = new PreCheckTask(username, password, connConf, dataBaseType, splitPK);
3、进行表切分,在PreCheckTask的call方法中
@Override
public Boolean call() throws DataXException {
……
List<Object> splitPkSqls = this.connection.getList(Key.SPLIT_PK_SQL, Object.class);
……
try {
for (int i = 0; i < querySqls.size(); i++) {
String splitPkSql = null;
String querySql = querySqls.get(i).toString();
……
/*verify splitPK*/
try {
if (splitPkSqls != null && !splitPkSqls.isEmpty()) {
splitPkSql = splitPkSqls.get(i).toString();
DBUtil.sqlValid(splitPkSql, dataBaseType);
if (i == 0) {
SingleTableSplitUtil.preCheckSplitPk(conn, splitPkSql, fetchSize, table, userName);
}
}
} catch (ParserException e) {
……
}
}
} finally {
DBUtil.closeDBResources(null, conn);
}
return true;
}
duhongjun
这个人很懒,什么都没留下
文章评论