使用Impala在kudu中创建含中文字段名的表

Impala版本: 2.7.0+cdh5.10.2+0

Kudu版本:1.4.0+cdh5.12.0+0

Hue版本:3.9.0+cdh5.10.2+4153

因业务需要,需要在kudu中创建含有中文字段的表。原来的方案是直接在Hue中Impala查询界面执行建表脚本,但是表中含有中文字段时,就会执行出错,建表脚本和出错信息如下:    

建表脚本:

create table if not exists kudu_test(
    `id` string,
    `字段1` string,
    `字段2` string,
    PRIMARY KEY (id)
)
PARTITION BY HASH (id) PARTITIONS 4
stored as kudu;
错误信息:
  • AnalysisException: Invalid column/field name: 字段1

上述错误为Impala抛出的异常,相关源码如下:

 public void analyze(Analyzer analyzer) throws AnalysisException {
    // Check whether the column name meets the Metastore's requirements.
    if (!MetaStoreUtils.validateName(colName_)) {
      throw new AnalysisException("Invalid column/field name: " + colName_);
    }
    if (typeDef_ != null) {
      typeDef_.analyze(null);
      type_ = typeDef_.getType();
    }
    Preconditions.checkNotNull(type_);
    Preconditions.checkState(type_.isValid());
    if (hasKuduOptions()) {
      Preconditions.checkNotNull(analyzer);
      analyzeKuduOptions(analyzer);
    }
    // Check HMS constraints on comment.
    if (comment_ != null &&
        comment_.length() > MetaStoreUtil.CREATE_MAX_COMMENT_LENGTH) {
      throw new AnalysisException(String.format(
          "Comment of column '%s' exceeds maximum length of %d characters:\n" +
          "%s has %d characters.", colName_, MetaStoreUtil.CREATE_MAX_COMMENT_LENGTH,
          comment_, comment_.length()));
    }
  }

为了能够在Kudu中创建含中文字段的表,并通过Impala查询该表,可以有以下方案:

方案一:修改Impala源码。但是鉴于本人能力有限,担心源码修改后,会产生其他未知异常,因此放弃该方案。

方案二:通过kudu的API创建含中文字段的表,然后在Impala中创建外部表进行关联。下面详细介绍该方案。

1、调用Kudu的JavaAPI,创建含有中文字段的表,代码如下:

public static void createTable(){
        KuduClient client = new KuduClient.KuduClientBuilder("127.0.0.1:7051").build();
        List<ColumnSchema> columns = new LinkedList<ColumnSchema>();
        columns.add(newColumn("id", Type.STRING, true));
        columns.add(newColumn("字段1", Type.STRING, false));
        columns.add(newColumn("字段2", Type.STRING, false));
        Schema schema = new Schema(columns);
        CreateTableOptions options = new CreateTableOptions();
        // 设置表的replica备份和分区规则
        List<String> parcols = new LinkedList<String>();
        parcols.add("id");
        // replica数量
        options.setNumReplicas(3);
        // hash分区的列
        options.addHashPartitions(parcols, 10);
        try {
            client.createTable("kudu_test", schema, options);
        } catch (KuduException e) {
            e.printStackTrace();
        }finally {
            try {
                client.close();
            } catch (KuduException e) {
                e.printStackTrace();
            }
        }
    }

2、在Imapla中创建上述Kudu表的外部表,脚本如下:

CREATE EXTERNAL TABLE IF NOT EXISTS kudu_test
STORED AS KUDU
TBLPROPERTIES (
  'kudu.table_name' = 'kudu_test'
);

3、当查询上述外部表的时候会有如下错误信息:

  • AnalysisException: Failed to load metadata for table: 'kudu_test' CAUSED BY: TableLoadingException: Add request failed : INSERT INTO `COLUMNS_V2` (`CD_ID`,`COMMENT`,`COLUMN_NAME`,`TYPE_NAME`,`INTEGER_IDX`) VALUES (?,?,?,?,?)

这是因为Impala在存储kudu表的元数据信息时,原数据表的字段编码不支持中文导致的。以下是COLUMNS_V2表的相关信息


4、解决Impala元数据不支持中文

找到Imapla的元数据库中(我的元数据库名为metastore),在该元数据库修改COLUMNS_V2表中字段的编码格式,可以执行如下SQL:

ALTER TABLE `COLUMNS_V2` CHANGE `COMMENT` `COMMENT` VARCHAR(256) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL;
ALTER TABLE `COLUMNS_V2` CHANGE `COLUMN_NAME` `COLUMN_NAME` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL;
ALTER TABLE `COLUMNS_V2` CHANGE `TYPE_NAME` `TYPE_NAME` VARCHAR(4000) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL;

执行完上述SQL,刷新下Impala的元数据,就能在Impala中查询含有中文字段的kudu表了。



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值