文档章节

Hive 2.1.1字段和表注释中文乱码

JackieYeah
 JackieYeah
发布于 2016/09/04 11:28
字数 1286
阅读 3054
收藏 4

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


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

CREATE TABLE IF NOT EXISTS employees (
    name STRING COMMENT '姓名',
    salary FLOAT COMMENT '薪水',
    subordinates ARRAY<STRING> COMMENT '下属',
    deductions MAP<STRING, FLOAT> COMMENT '扣除金额',
    address STRUCT<street:STRING, city:STRING, state:STRING, zip:INT> 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 语句查看表结构,发现字段注释全是乱码:

desc

desc formatted employees

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

desc_formatted

show create table employees

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

error-encode


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

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

hive-utf8

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

hive-latin

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

以下语句是为了支持 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 编码。

desc-formatted_fix1

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

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

patch

方便做个记录,现将 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 编码。

desc-formatted_fix1

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

show_create_fix2

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

patch2

方便做个记录,现将 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<String, String> params, StringBuilder tableInfo) {
     List<String> keys = new ArrayList<String>(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 查看表结构,发现表和字段注释都可以正常显示中文。

desc_formatted_fix2]

© 著作权归作者所有

共有 人打赏支持
JackieYeah
粉丝 45
博文 70
码字总数 90004
作品 0
武汉
程序员
待分析日志文件的编码格式不是utf8的情况,hive要怎么处理才不乱码?

未进行任何处理的情况: 中文字段出现乱码情况 把表改为gbk编码的情况: 中文字段正常,但是日期字段格式又混乱了 先对日志文件进行转码为utf-8再导入的情况: 中文字段正常,时间字段也正常...

进击的巨喵
2017/02/10
124
0
【解决】Hive 使用 mysql 作为 metastore 元数据库时UTF-8编码的问题

在最最初配置 MySQL 数据库的时候,就设置成 UTF-8 的编码 2. 然后在 metastore 库生成后,如果直接用 hive 创建库或表就会报错,Specified key was too long; max key length is 767 bytes...

自东土大唐而来
01/16
17
0
sqoop将oracle数据表导入hive中文乱码问题

请教各位大神一个问题,就是将oracle的表导入到hive后中文乱码,oracle库的编码格式为US7ASCII,各位大神有没有遇到过类型的问题,或者有没有好的解决方案建议,谢谢了。附注:现在已经试过c...

aggregated_data
2015/11/30
781
0
pljson.tar 中的to_char方法乱码

我oracle服务端客户端的字符集都是utf8,我在plsql的sql窗口中查询T表的c字段,显示中文正常。 我写了一个存储过程,过程里面创建了一个json对象J,然后将T表的c字段put到json对象J中,最后调...

pixiaozheng
2013/05/23
243
1
postgresql----COPY之表与文件之间的拷贝

postgresql提供了COPY命令用于表与文件(和标准输出,标准输入)之间的相互拷贝,copy to由表至文件,copy from由文件至表。 示例1.将整张表拷贝至标准输出 test=# copy tbl_test1 to stdout;...

wangxuwei
2016/10/27
3
0

没有更多内容

加载失败,请刷新页面

加载更多

no such module 'pop'问题

在github上 clone 了一个 swift 项目,编译时提示"no such module 'POP'"错误,查了一下居然是因为podfile中指定的最低版本是iOS 11.0,大于我测试手机的iOS版本10.3.3,将Podfile中的最低版...

yoyoso
22分钟前
0
0
redis 系列一 -- 简介及安装

1.简介 redis -- remote dictionary server 远程字典服务 使用 C 语言编写; 高性能的 key-value数据库; 内存数据库,支持数据持久化。 Redis 是一个开源(BSD许可)的,内存中的数据结构存...

imbiao
45分钟前
1
0
nginx log记录请求响应时间

有时为了方便分析接口性能等,需要记录请求的时长,通过修改nginx的日志格式可以做到,如 添加一个新的log_format log_format timed_combined '$remote_addr - $remote_user [$time_local] "...

swingcoder
今天
2
0
Spring MVC之RequestMappingHandlerMapping匹配

对于RequestMappingHandlerMapping,使用Spring的同学基本都不会陌生,该类的作用有两个: 通过request查找对应的HandlerMethod,即当前request具体是由Controller中的哪个方法进行处理; 查...

爱宝贝丶
今天
2
0
Java Web--增删改查之二界面后台java代码(转载参考)

/** *  *//** * @author Administrator * */package dao; import java.sql.*;public class DBConn {/** * 链接数据库 * @return */  ...

小橙子的曼曼
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部