无法在具有自定义分隔符的配置单元中插入数据

Posted

技术标签:

【中文标题】无法在具有自定义分隔符的配置单元中插入数据【英文标题】:unable to insert data in hive having custom delimiter 【发布时间】:2016-10-30 19:28:42 【问题描述】:

我正在尝试学习 hive,这可能是一个愚蠢的问题,但是 我在 hive 中创建了一个表,如下所示

create table if not exists tweets_table( 
     tweetdata STRING,
     followerscount INT,
     friendscount INT,
     statuscount INT,
     retweetcount INT,
     favouritescount INT,
     lang STRING,
     placefullname STRING,
     placename STRING,
     countryname STRING,
     countrycode STRING,
     hashtags STRING)
     ROW FORMAT DELIMITED
     FIELDS TERMINATED BY '^**^'
     LINES TERMINATED BY '\n'
     STORED AS TEXTFILE;

LOAD  DATA LOCAL INPATH  '/home/cloudera/Desktop/TestDB.txt' INTO TABLE tweets_table5 ;

我使用'^**^'来分隔文本,因为推文中有很多“\n \r”(如果有,请提出标准做法)

所以我有一个要加载的文本文件

09-09-2016 10:51:33|^**^|@ArvindKejriwal @abpnewstv तुम्हारे दावों का क्या हुआ केजरीवाल।|^**^|74|^**^|30|^**^|0|^**^|98|^**^|0|^**^|49|^**^|en|^**^|Ambikapur, India|^**^|Ambikapur|^**^|India|^**^|IN|^**^|[]
09-09-2016 10:51:37|^**^|@LiveLawIndia It is shocking a judge  arrested. I am sure Higher Judiciary will come their rescue , Judges per se cannot be wrong|^**^|0|^**^|14|^**^|0|^**^|32|^**^|0|^**^|2|^**^|en|^**^|Rajasthan, India|^**^|Rajasthan|^**^|India|^**^|IN|^**^|[]

成功加载并查询后, 我得到以下输出

 09-09-2016 10:51:33|   NULL    NULL    NULL    NULL    NULL    |30|    **  |0| **  |98|    **
 09-09-2016 10:51:37|   NULL    NULL    NULL    NULL    NULL    |14|    **  |0| **  |32|    **

我不明白我哪里出错了,是在我的 tex tfile 还是 hive 表中。请帮忙

【问题讨论】:

【参考方案1】:

你正在尝试做的几个问题:

使用FIELDS TERMINATED BY 分隔符不能超过 1 个字符。

即使这样有效,也不能解决您的推文中包含行分隔符的问题 - 推文中的每个 \n 都会开始一个新行。

您描述表格的方式 - 无法正确解析 - 您不能将 \n 作为行分隔符和推文数据。如果您是生成此输入文件的人,我建议将推文中的所有\n\r 替换为空格。

【讨论】:

【参考方案2】:

用regex serde 代替默认的hive serde 创建表。

根据列数修改下面的正则表达式:

^(.+)\|\^\*\*\^\|(.+)\|\^\*\*\^\|(.+)\|\^\*\*\^\|(.+)\|\^\*\*\^\|(.+)\|\^\*\*\^\|(.+)\|\^\*\*\^\|(.+)\|\^\*\*\^\|(.+)\|\^\*\*\^\|(.+)\|\^\*\*\^\|(.+)\|\^\*\*\^\|(.+)\|\^\*\*\^\|(.+)\|\^\*\*\^\|(.+)\|\^\*\*\^\|(.+)$

表格:

create external table if not exists tweets_table( 
     tweetdata STRING,
     followerscount INT,
     friendscount INT,
     statuscount INT,
     retweetcount INT,
     favouritescount INT,
     lang STRING,
     placefullname STRING,
     placename STRING,
     countryname STRING,
     countrycode STRING,
     hashtags STRING)
ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.RegexSerDe'
WITH SERDEPROPERTIES  (
"input.regex" = " ^(.+)\|\^\*\*\^\|(.+)\|\^\*\*\^\|(.+)\|\^\*\*\^\|(.+)\|\^\*\*\^\|(.+)\|\^\*\*\^\|(.+)\|\^\*\*\^\|(.+)\|\^\*\*\^\|(.+)\|\^\*\*\^\|(.+)\|\^\*\*\^\|(.+)\|\^\*\*\^\|(.+)\|\^\*\*\^\|(.+)\|\^\*\*\^\|(.+)\|\^\*\*\^\|(.+)$",
"output.format.string" = "%1$s %2$s %3$s %4$s %5$s %6$s %7$s %8$s %9$s %10$s %11$s %12$s %13$s"
)
STORED AS TEXTFILE;

加载数据:

LOAD  DATA LOCAL INPATH  '/home/cloudera/Desktop/TestDB.txt' INTO TABLE tweets_table ;

如果你得到RegexSerDe classNotFoundException 然后添加正则表达式 serde jar:

ADD JAR hive-contrib=x.x.x.jar

【讨论】:

这个正则表达式正是我正在寻找的,但是,我收到一个错误 FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask。 java.util.regex.PatternSyntaxException:在索引 9 附近悬挂元字符 '*' ^(.+)|^**^|(.+)|^**^|(.+)|^**^|(. +)|^**^|(.+)|^**^|(.+)|^**^|(.+)|^**^|(.+)|^**^|(. +)|^**^|(.+)|^**^|(.+)|^**^|(.+)|^**^|(.+)|^**^|(. +)$ 移除 output.format.string 参数。将您的文件放在 hdfs 中,而不是使用此正则表达式创建外部表,而不是内部表。

以上是关于无法在具有自定义分隔符的配置单元中插入数据的主要内容,如果未能解决你的问题,请参考以下文章

如何在配置单元表中插入具有地图列的数据框

如何在配置单元插入查询中忽略输入开始

如何将原始数据插入具有不同列序列的配置单元表中?

Hive:如何处理数据文件中有分隔符的文件?

UITableview 默认单元格中的自定义分隔符显示意外行为

如何将具有自定义枚举类型的数据从 csv 插入现有的 PostgreSQL 表