datax之源码优化

CommonRdbmsWriter 类里 
fillPreparedStatementColumnType方法里

 String str = column.asString();
                    if (DataBaseType.PostgreSQL.compareTo(dataBaseType)==0&&StringUtils.isNotEmpty(str)&&str.indexOf('\u0000')>-1){
                        //如果writer是postgresql  并且字段类型是text vachar  然后值value!=null  同时含有这个特殊字符
                        str = str.replace('\u0000',' ').replace(" ","");
                    }
                    if (DataBaseType.Oracle.compareTo(dataBaseType)==0){
                        if (columnSqltype==Types.VARCHAR&&str!=null&&str.getBytes(StandardCharsets.UTF_8).length>=4000){
                                    //全中文3000字       9000 字节  -> 1333字符  4000字节
                                    //全英文5000字       5000字节   -> 4000字符  4000字节
                                    //中文1500 英文1000  字节5500   -> 2000(中1500英500)  5000字符 -> 1333字符
                                    str = str.substring(0, Math.min(str.length(), 4000));
                                    if (str.getBytes(StandardCharsets.UTF_8).length>=4000){
                                        str = str.substring(0, 1333); //直接认为全是中文
                                    }
                        }
                        if (columnSqltype==Types.NVARCHAR&&str!=null&&str.length()>=2000){
                            //2000中文   2000英文
                            if (str.getBytes(StandardCharsets.UTF_8).length>2000){
                                //有中文
                                str = str.substring(0, 1333);
                            }else { //有中英文
                                str= str.substring(0, 1500 );
                            }
                        }
                    }
                    preparedStatement.setString(columnIndex + 1, str);
                    break;

说下优化点

1.优化输出到postgresql里时候 有个特殊字符\u0000 在插入的时候会报错直接替换为无了。这个不会影响结果,因为这个字符本身大多时候就没有意义

2.优化oraclewriter时,由于hive的string是不限长度的,但是oracle的varhcar2最长是4000字节,1333汉字,nvarchar2000是2000字符。

但是在insert into  oracle_table values ("2000个汉字的时候") 会报一个下面的错 【仅能绑定要插入的LONG列的LONG值的错】

在insert into  oracle_table values ("1500个汉字的时候") 不会报错....

但是在直接向表里粘贴2000汉字时候,不会报错

有熟悉这块的可以自行更改。。这个改动的目的是保证所有数据都插入到oracle即使部分数据残缺。

DfsUtils类。如果你们新增了decimal字段类型。

注意该字段bug极多...

在读取parquet文件的时候

 private void transportParquetRecord(Group group, List<String> columnName,
                                        List<String> columnType,
                                        List<String> columnValue,
                                        List<Integer> columnIndex,
                                        RecordSender recordSender, TaskPluginCollector taskPluginCollector){
        Record record = recordSender.createRecord();
        Column columnGenerated = null;
        try {
            //type不能为空
            for (int i = 0; i < columnType.size(); i++){
                String type = columnType.get(i);
                if (columnValue.get(i)!=null){ //针对分区表 的分区字段 因为我这个自带有value 那么说明是自己定义的字段
                        columnGenerated=new StringColumn(columnValue.get(i));
                }else {
                    if (0 != group.getFieldRepetitionCount(i)){//数据不为空
                        if (type.equalsIgnoreCase("INT")){
//                        LOG.info(String.format("Read parquetfile group value  : [%s].", group.getInteger(columnName.get(i),0)));
                            if (columnName.get(i)!=null){// 写的是{"name":xx,"type:"xx"}
                                columnGenerated =  new StringColumn(String.valueOf(group.getInteger(columnName.get(i),0))) ;
                            }else {
                                columnGenerated =  new StringColumn(group.getValueToString(columnIndex.get(i),0)) ;
                            }
                        }else if(type.equalsIgnoreCase("STRING")){
//                        LOG.info(String.format("Read parquetfile group value  : [%s].", group.getString(columnName.get(i),0)));
                            if (columnName.get(i)!=null){
                                columnGenerated =  new StringColumn(String.valueOf(group.getString(columnName.get(i),0))) ;
                            }else {
                                columnGenerated =  new StringColumn(group.getValueToString(columnIndex.get(i),0)) ;
                            }
                        }else if(type.equalsIgnoreCase("DOUBLE")){
//                        LOG.info(String.format("Read parquetfile group value  : [%s].", group.getDouble(columnName.get(i),0)));
                            if (columnName.get(i)!=null){
                                columnGenerated =  new StringColumn(String.valueOf(group.getDouble(columnName.get(i),0))) ;
                            }else {
                                columnGenerated =  new StringColumn(group.getValueToString(columnIndex.get(i),0)) ;
                            }
                        }else if(type.equalsIgnoreCase("BIGINT")){
//                        LOG.info(String.format("Read parquetfile group value  : [%s].", group.getInt96(columnName.get(i),0)));
                            if (columnName.get(i)!=null){
                                columnGenerated =  new StringColumn(String.valueOf(group.getInt96(columnName.get(i),0))) ;
                            }else {
                                columnGenerated =  new StringColumn(group.getValueToString(columnIndex.get(i),0)) ;
                            }
                        }else if (type.equalsIgnoreCase("DECIMAL")){
                            //https://www.shuzhiduo.com/A/rV57W2yE5P/
                            byte[] bytes;
                            if(columnName.get(i)!=null){
                                bytes= group.getBinary(columnName.get(i), 0).getBytes();
                            }else {
                                bytes=group.getBinary(columnIndex.get(i), 0).getBytes();
                            }
                            java.math.BigDecimal result = new BigDecimal(new BigInteger(bytes), 18);
                            columnGenerated = new StringColumn(result.toPlainString());
                        }
                    }else { //数据为空的情况
//                    LOG.info(String.format("Read parquetfile group null  : [%s].", group.getString(columnName.get(i),0)));             if (printFlag==0&&i==(columnType.size()-1))
                        columnGenerated =new StringColumn(null);
                    }
                }

                record.addColumn(columnGenerated);
            }
//            if (printFlag==0){
//                LOG.info("record={}",record);
//            }
            recordSender.sendToWriter(record);
        } catch (Exception e) {
            taskPluginCollector
                    .collectDirtyRecord(record, e.getMessage());
        }
    }

decimla 不能直接转string 否则decimal 0.000000000的时候会直接变为 0E-18 

新增的kudu11writer。写的很垃圾 让我怀疑ali的水平了。

Kudu11xHelper.java

前脚刚设置为long 后脚就强转为int ,666

不支持decimal。 kudu更类似与rdbm关系型数据库,又不像hive那样存储格式很麻烦。。不知道为啥不加上

ColumnType.java

 KuduWriterTask.java

 

此处第一新增了支持decimal 

 第二 对于时间格式的处理。

例如oracle date类型2022-05-20 存到kudu的string 。他不会存2022-05-20,它会存个时间戳。

上面的是最开始报错。下面的是我解决后的

 这里分析下原因。 我们从oracle读的时候会获取到date 2022-05-20,然后存到dateColumn里。

 原文是  column.getRawData().toString。

可以看到dateColumn实际存的是date.getTime 所以变成了时间戳。

我们至于要 column.asString就行

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值