在我们的用例中,我们得到的UTF-8文本数据格式如下:
Data1§Data2
Data3§Data4
现在我们希望将Data1和Data3放在一个列中,Data2和Data4放在Apache Hive的一列中 . 听起来很简单 .
但是,我们无法将§字符(即unicode U 00A7 "Section Sign"参见here)指定为字段分隔符 .
我们尝试了以下方法,没有任何结果可以达到 .
1)使用通过接近终止的正常字段
ROW FORMAT DELIMITED FIELDS TERMINATED BY '§'
返回(注意附加到每个单元格的?,在其他客户端中注明未识别标志的unicode标志)
+--------------------+--------------------+--+
| test.column1 | test.column2 |
+--------------------+--------------------+--+
| Data1? | Data2? |
| Data3? | Data4? |
+--------------------+--------------------+-
或八进制表示
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\247'
要么
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\304\247'
返回:
+--------------------+--------------------+--+
| test.column1 | test.column2 |
+--------------------+--------------------+--+
| Data1?Data2 | NULL |
| Data3?Data4 | NULL |
+--------------------+--------------------+--+
2)使用RegexSerDe
ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
"input.regex" = "^([^\\]]+)\\\247([^\\]]+)$")
(将字段分隔符更改为/在某些测试源数据中并使用\ 057(八进制为/)会产生正确的结果,但更改源数据对我们来说是不可行的 . )
要么
ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
"input.regex" = "^([^\\]]+)\\$([^\\]]+)$")
(在描述格式化的表语句中,这会产生:
input.regex ^([^\\]]+)\\\uFFFD\uFFFD([^\\]]+)$
其中\ uFFFD是未识别标志的unicode表示)
SELECT的结果总是一样的:
+--------------------+--------------------+--+
| test.column1 | test.column2 |
+--------------------+--------------------+--+
| NULL | NULL |
| NULL | NULL |
+--------------------+--------------------+--+
My research so far indicates the following:
1)Hive无法使用不可打印的ASCII字符,其中的八进制数高于177.在github上的其他一些代码here中,我的意外指向令我惊讶的是:
Hive可以在'\ ooo'形式中指定分隔符,其中ooo是介于000和177之间的三位八进制数 .
2)此外,我发现证据表明只有一个字节的字符可以用作BigSQL文档中的字段分隔here(但不在官方文档中),它说:
分隔符必须是单字节字符
至于我的研究§(unicode U 00A7)是一个2字节的字符(11000010:10100111)
Does this mean I can not use this delimiter or is there any other ways to use it?
小更新,如果这仍然没有解决,有人需要它:
我尝试了以下方法将数据暂存为单列表,然后将§转换为(逗号),然后用逗号分隔 . 这适用于小样本数据,但对于具有错误的200列的较大 生产环境 表失败 .
select
split(a.textcolumn, '\\,')[0] as column1
,split(a.textcolumn, '\\,')[1] as column2
from
(select translate(textcolumn, '§', ',') as textcolumn from database.stage) a;
这是错误:
SQL错误:java.io.IOException:org.apache.hadoop.hive.ql.metadata.HiveException:错误评估translate(stagingstring,'§',';')java.io.IOException:org.apache.hadoop.hive .ql.metadata.HiveException:错误评估translate(stagingstring,'§',';')java.io.IOException:org.apache.hadoop.hive.ql.metadata.HiveException:错误评估translate(stagingstring,'§' ,';')org.apache.hadoop.hive.ql.metadata.HiveException:错误评估translate(stagingstring,'§',';')org.apache.hadoop.hive.ql.metadata.HiveException:错误评估翻译(stagingstring,'§',';')java.lang.IllegalArgumentException:null
更新2:
上面的方法有效,但如果源数据不干净(有其他UTF-8问题),它将抛出上述错误 .