comment hive_Hive 2.1.1字段和表注释中文乱码

##问题背景 一般我们创建 Hive 表时都需要给表和字段加上注释以便理解表的用途与字段的含义。但是往往在创建 Hive 表后查看表结构发现中文注释乱码,比较头疼。本文总结了一下针对这种情况的解决方案。

##问题重现 ###创建带中文注释的Hive表employees 使用 CREATE TABLE 语法创建一个带有中文注释的 Hive 表 employees:

CREATE TABLE IF NOT EXISTS employees (

name STRING COMMENT '姓名',

salary FLOAT COMMENT '薪水',

subordinates ARRAY COMMENT '下属',

deductions MAP COMMENT '扣除金额',

address STRUCT COMMENT '住址'

) COMMENT '员工表'

ROW FORMAT DELIMITED

FIELDS TERMINATED BY '\001'

COLLECTION ITEMS TERMINATED BY '\002'

MAP KEYS TERMINATED BY '\003'

LINES TERMINATED BY '\n'

STORED AS TEXTFILE;

desc employees

使用 desc employees 语句查看表结构,发现字段注释全是乱码:

13f108c2de8893e03f5b94a34c6d24ae.png

desc formatted employees

使用 desc formatted employees 语句查看表结构,发现表和字段注释全是乱码:

2ca4d29794e866dbd756d0168734cc0c.png

show create table employees

最后使用 show create table employees 语句查看 employees 建表信息,也发现表和字段注释全是乱码:

ae438ae21659ae1ecfe18df94a3b8841.png

##问题解决方案 ###修改Hive元数据库编码 当使用 MySQL 作为 Hive 元数据库的时候, Hive 元数据库的字符集要设置成 latin1 default。

使用 show create database hive 语句查看 hive 数据库默认编码。

52bd27237369bba356f3fd37544aa030.png

使用 alter database hive default character set latin1 将 hive 数据库默认编码改成 latin1。

4617c802a6cfba1f90ef31544a9e88dc.png

###修改相关表相关字段编码

以下语句是为了支持 Hive 建表时插入中文注释

alter table COLUMNS_V2 modify column COMMENT varchar(256) character set utf8;

alter table TABLE_PARAMS modify column PARAM_VALUE varchar(4000) character set utf8;

alter table PARTITION_PARAMS modify column PARAM_VALUE varchar(4000) character set utf8;

alter table PARTITION_KEYS modify column PKEY_COMMENT varchar(4000) character set utf8;

alter table INDEX_PARAMS modify column PARAM_VALUE varchar(4000) character set utf8;

###验证结果 重新创建 employees 表。

使用 desc employees 语句查看表结构,发现字段注释可以正常显示中文。

使用 desc formatted employees 语句查看表结构, 发现字段注释可以正常显示中文,但是表注释显示的虽然不是乱码,但却是 Unicode 编码。

f3403bd74dc1b20aa396ebfed4d5df88.png

使用 show create table employees 语句查看建表信息,发现表和字段注释仍然都是乱码。

2038ad6c72d99ead39c5b93650ae013f.png

###打Patch Hive 表注释中文乱码是 Hive 的一个 bug, 详情参见 注释不能支持Unicode字符 。在 2.1.1 版本中还未解决这个bug, 所以需要自己手动打patch。链接中已经提供了patch文件:

28a6a76d8577b9e2c28fc169d6c5c03b.png

方便做个记录,现将 HIVE-11837.1.patch 内容粘贴出来:

diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/DDLTask.java b/ql/src/java/org/apache/hadoop/hive/ql/exec/DDLTask.java

index 6fca9f7ec86574a6053af3672c551c6a63aa4870..661367f27b69f9796140808eda53a3bbcdcbdb11 100644

--- a/ql/src/java/org/apache/hadoop/hive/ql/exec/DDLTask.java

+++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/DDLTask.java

@@ -2048,7 +2048,7 @@ private int showCreateTable(Hive db, DataOutputStream outStream, String tableNam

if (tbl.isView()) {

String createTab_stmt = "CREATE VIEW `" + tableName + "` AS " + tbl.getViewExpandedText();

- outStream.writeBytes(createTab_stmt.toString());

+ outStream.write(createTab_stmt.toString().getBytes("UTF-8"));

return 0;

}

@@ -2196,7 +2196,7 @@ else if (sortCol.getOrder() == BaseSemanticAnalyzer.HIVE_COLUMN_ORDER_DESC) {

}

createTab_stmt.add(TBL_PROPERTIES, tbl_properties);

- outStream.writeBytes(createTab_stmt.render());

+ outStream.write(createTab_stmt.render().getBytes("UTF-8"));

} catch (IOException e) {

LOG.info("show create table: " + stringifyException(e));

return 1;

前面的 + 号表示需要新加的代码,- 号表示需要删除的代码。

接下来下载 Hive 2.1.1 源码包 apache-hive-2.1.1-src.tar.gz,然后解压。修改 DDLTask.java 源码,接着使用以下Maven命令进行编译打包。

mvn clean package -DskipTests=true

最后,将新生成的 hive-exec-2.1.1.jar 文件替换掉 $HIVE_HOME/lib 目录下的 hive-exec-2.1.1.jar 文件。

验证结果

重启 Hive 客户端 ,然后重新创建 employees 表。

使用 desc employees 语句查看表结构,发现字段注释可以正常显示中文。

使用 desc formatted employees 语句查看表结构, 发现字段注释可以正常显示中文,但是表注释显示的虽然不是乱码,但却是 Unicode 编码。

f3403bd74dc1b20aa396ebfed4d5df88.png

使用 show create table employees 语句查看建表信息, 发现表和字段注释都可以正常显示中文。

d1cc689fba00bfd8c765432b3aabc0a6.png

###解决desc formatted中文变成 Unicode 编码 还是需要打patch, 具体参见 https://issues.apache.org/jira/browse/HIVE-5682。链接中已经提供了patch文件:

936d238ca0cbc393c1d20e0086f9a39b.png

方便做个记录,现将 HIVE-5682.patch 内容粘贴出来:

### Eclipse Workspace Patch 1.0

#P hive-0.12.0-jd-svn

Index: ql/src/java/org/apache/hadoop/hive/ql/metadata/formatting/MetaDataFormatUtils.java

===================================================================

--- ql/src/java/org/apache/hadoop/hive/ql/metadata/formatting/MetaDataFormatUtils.java(revision 29)

+++ ql/src/java/org/apache/hadoop/hive/ql/metadata/formatting/MetaDataFormatUtils.java(working copy)

@@ -28,6 +28,8 @@

import java.util.Set;

import org.apache.commons.lang.StringEscapeUtils;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

import org.apache.hadoop.hive.conf.HiveConf;

import org.apache.hadoop.hive.metastore.TableType;

import org.apache.hadoop.hive.metastore.api.FieldSchema;

@@ -47,7 +49,7 @@

*

*/

public final class MetaDataFormatUtils {

-

+ private static final Log LOG = LogFactory.getLog("org.apache.hadoop.hive.ql.metadata.formatting.MetaDataFormatUtils");

public static final String FIELD_DELIM = "\t";

public static final String LINE_DELIM = "\n";

@@ -262,10 +264,20 @@

private static void displayAllParameters(Map params, StringBuilder tableInfo) {

List keys = new ArrayList(params.keySet());

+ String value = null;

Collections.sort(keys);

for (String key : keys) {

tableInfo.append(FIELD_DELIM); // Ensures all params are indented.

- formatOutput(key, StringEscapeUtils.escapeJava(params.get(key)), tableInfo);

+ value = params.get(key);

+ LOG.info(">>lvxin displayAllParameters:key="+key+";params.get(key)="+params.get(key));

+ if("comment".equals(key)&& null!=value && value.getBytes().length!=key.length())

+ {

+ formatOutput(key, value, tableInfo);

+ }

+ else

+ {

+ formatOutput(key, StringEscapeUtils.escapeJava(value), tableInfo);

+ }

}

}

前面的 + 号表示需要新加的代码,- 号表示需要删除的代码。

同样的修改 MetaDataFormatUtils 源码,接着使用以下Maven命令进行编译打包。

mvn clean package -DskipTests=true

最后,将新生成的 hive-exec-2.1.1.jar 文件替换掉 $HIVE_HOME/lib 目录下的 hive-exec-2.1.1.jar 文件。

###验证结果 重启 Hive 客户端。

使用 desc formatted employees 查看表结构,发现表和字段注释都可以正常显示中文。

e36f171b8beea8ea52e706e1a60f14be.png]

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值