【问题标题】:Hive: select column with non alphanumeric charactersHive:选择具有非字母数字字符的列
【发布时间】:2016-05-22 12:47:36
【问题描述】:

我正在使用 Hive 0.13.0,我希望它可以处理具有非字母数字字符的表名和列名,如 documentation 中所述,但事实并非如此。

我已经能够创建一个列名带有点的表格,例如:

hive> create external table frb_test (recvTime string, fiwareServicePath string, entityId string, entityType string, `ORL.SOU.DH.SSTA10.T.HVAC.HeatLoad` string, `ORL.SOU.DH.SSTA10.T.HVAC.HeatLoad_md` array<struct<name:string,type:string,value:string>>) row format serde 'org.openx.data.jsonserde.JsonSerDe' location '/user/frb/test'; 
OK
Time taken: 0.286 seconds

如你所见,我使用https://github.com/rcongiu/Hive-JSON-Serde作为Json serde。不过,下面是hdfs:///user/frb/test的内容:

$ hadoop fs -cat /user/frb/test/deleteme
{"recvTime":"2016-02-09T18:03:48.986Z","fiwareServicePath":"orl_sou","entityId":"ORL.SOU.DH.SSTA10","entityType":"ETS", "ORL.SOU.DH.SSTA10.T.HVAC.HeatLoad":"10.673299789428711", "ORL.SOU.DH.SSTA10.T.HVAC.HeatLoad_md":[{"name":"dofTimestamp","type":"ms","value":"2016-02-08T23:00:00.000Z"},{"name":"tag","type":"text","value":"ORL.SOU.DH.SSTA10.T.HVAC.HeatLoad"},{"name":"description","type":"text","value":"Electrical heat load"},{"name":"quality","type":"0:GOOD, +0:ERROR","value":"10813440"},{"name":"max","type":"max","value":"null"},{"name":"min","type":"min","value":"null"},{"name":"lcl","type":"lcl","value":"null"},{"name":"ucl","type":"ucl","value":"null"}]}

我无法选择orl.sou.dh.ssta10.t.hvac.heatload 列:

hive> add jar /home/frb/json-serde-1.3.7-jar-with-dependencies.jar;
hive> select `orl.sou.dh.ssta10.t.hvac.heatload` from frb_test;                                                                                                                    Total jobs = 1                                                                                                                                            
Launching Job 1 out of 1
Number of reduce tasks is set to 0 since there's no reduce operator
Starting Job = job_1455032234756_0008, Tracking URL = http://namenode.fiware.org:8088/proxy/application_1455032234756_0008/
Kill Command = /opt/cloudera/parcels/CDH-5.3.2-1.cdh5.3.2.p0.10/lib/hadoop/bin/hadoop job  -kill job_1455032234756_0008
Hadoop job information for Stage-1: number of mappers: 1; number of reducers: 0
2016-02-11 17:05:56,150 Stage-1 map = 0%,  reduce = 0%
2016-02-11 17:06:23,653 Stage-1 map = 100%,  reduce = 0%
Ended Job = job_1455032234756_0008 with errors
Error during job, obtaining debugging information...
Examining task ID: task_1455032234756_0008_m_000000 (and more) from job job_1455032234756_0008

Task with the most failures(4): 
-----
Task ID:
  task_1455032234756_0008_m_000000

URL:
  http://namenode.fiware.org:8088/taskdetails.jsp?jobid=job_1455032234756_0008&tipid=task_1455032234756_0008_m_000000
-----
Diagnostic Messages for this Task:
Error: java.lang.RuntimeException: Error in configuring object
    at org.apache.hadoop.util.ReflectionUtils.setJobConf(ReflectionUtils.java:109)
    at org.apache.hadoop.util.ReflectionUtils.setConf(ReflectionUtils.java:75)
    at org.apache.hadoop.util.ReflectionUtils.newInstance(ReflectionUtils.java:133)
    at org.apache.hadoop.mapred.MapTask.runOldMapper(MapTask.java:446)
    at org.apache.hadoop.mapred.MapTask.run(MapTask.java:343)
    at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:168)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.java:416)
    at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1642)
    at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:163)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:616)
    at org.apache.hadoop.util.ReflectionUtils.setJobConf(ReflectionUtils.java:106)
    ... 9 more
Caused by: java.lang.RuntimeException: Error in configuring object
    at org.apache.hadoop.util.ReflectionUtils.setJobConf(ReflectionUtils.java:109)
    at org.apache.hadoop.util.ReflectionUtils.setConf(ReflectionUtils.java:75)
    at org.apache.hadoop.util.ReflectionUtils.newInstance(ReflectionUtils.java:133)
    at org.apache.hadoop.mapred.MapRunner.configure(MapRunner.java:38)
    ... 14 more
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:616)
    at org.apache.hadoop.util.ReflectionUtils.setJobConf(ReflectionUtils.java:106)
    ... 17 more
Caused by: java.lang.RuntimeException: Map operator initialization failed
    at org.apache.hadoop.hive.ql.exec.mr.ExecMapper.configure(ExecMapper.java:157)
    ... 22 more
Caused by: java.lang.RuntimeException: cannot find field orl from [0:recvtime, 1:fiwareservicepath, 2:entityid, 3:entitytype, 4:orl.sou.dh.ssta10.t.hvac.heatload, 5:orl.sou.dh.ssta10.t.hvac.heatload_md]
    at org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorUtils.getStandardStructFieldRef(ObjectInspectorUtils.java:415)
    at org.apache.hadoop.hive.serde2.objectinspector.StandardStructObjectInspector.getStructFieldRef(StandardStructObjectInspector.java:150)
    at org.apache.hadoop.hive.ql.exec.ExprNodeColumnEvaluator.initialize(ExprNodeColumnEvaluator.java:79)
    at org.apache.hadoop.hive.ql.exec.Operator.initEvaluators(Operator.java:934)
    at org.apache.hadoop.hive.ql.exec.Operator.initEvaluatorsAndReturnStruct(Operator.java:960)
    at org.apache.hadoop.hive.ql.exec.SelectOperator.initializeOp(SelectOperator.java:65)
    at org.apache.hadoop.hive.ql.exec.Operator.initialize(Operator.java:376)
    at org.apache.hadoop.hive.ql.exec.Operator.initialize(Operator.java:460)
    at org.apache.hadoop.hive.ql.exec.Operator.initializeChildren(Operator.java:416)
    at org.apache.hadoop.hive.ql.exec.TableScanOperator.initializeOp(TableScanOperator.java:189)
    at org.apache.hadoop.hive.ql.exec.Operator.initialize(Operator.java:376)
    at org.apache.hadoop.hive.ql.exec.MapOperator.initializeOp(MapOperator.java:424)
    at org.apache.hadoop.hive.ql.exec.Operator.initialize(Operator.java:376)
    at org.apache.hadoop.hive.ql.exec.mr.ExecMapper.configure(ExecMapper.java:136)
    ... 22 more


FAILED: Execution Error, return code 2 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask
MapReduce Jobs Launched: 
Stage-Stage-1: Map: 1   HDFS Read: 0 HDFS Write: 0 FAIL
Total MapReduce CPU Time Spent: 0 msec

我已经看到管理 Hive 如何处理非字母数字字符的 Hive 属性是 hive.support.quoted.identifiers,它的值可以是 none(然后 Hive 表现为 0.12.0 版本)或 column,我猜它是 0.13.0 的默认值;尽管如此,我已经尝试设置它并没有结果:

hive> set hive.support.quoted.identifiers=column;
hive> select `orl.sou.dh.ssta10.t.hvac.heatload` from frb_test;              
Total jobs = 1
Launching Job 1 out of 1
Number of reduce tasks is set to 0 since there's no reduce operator
Starting Job = job_1455032234756_0009, Tracking URL = http://namenode.fiware.org:8088/proxy/application_1455032234756_0009/
Kill Command = /opt/cloudera/parcels/CDH-5.3.2-1.cdh5.3.2.p0.10/lib/hadoop/bin/hadoop job  -kill job_1455032234756_0009
...
Caused by: java.lang.RuntimeException: cannot find field orl from [0:recvtime, 1:fiwareservicepath, 2:entityid, 3:entitytype, 4:orl.sou.dh.ssta10.t.hvac.heatload, 5:orl.sou.dh.ssta10.t.hvac.heatload_md]
...
FAILED: Execution Error, return code 2 from
org.apache.hadoop.hive.ql.exec.mr.MapRedTask
MapReduce Jobs Launched: 
Stage-Stage-1: Map: 1   HDFS Read: 0 HDFS Write: 0 FAIL
Total MapReduce CPU Time Spent: 0 msec

【问题讨论】:

    标签: json hive


    【解决方案1】:

    我敢打赌,HQL 解析器将“点”字符视为访问 STRUCT 内部字段的一种方式,仅此而已。

    而且我敢打赌,在所有参与支持 Hive 中“引用标识符”的人中,没有人想到过在列名中带有“点”的测试用例。毕竟,到底谁会疯狂到在列名中使用“点”??

    好吧,也许吧。那么谁会疯狂地定义一个名称中带有“点”的 STRUCT 列,出于反常,只是为了在组合中添加一个额外的“点”??

    好的,让我们假设这可能会发生。那么那个假设的人会通过坚持使用第一个支持“引用标识符”的 Hive 版本来进一步推动变态吗?没有在实际生产系统中对该功能进行实战测试?并且没有机会从最终的错误修复中受益??

    我的 2 美分:因为您显然无法控制收到的垃圾 JSON,只需在其上运行快速 sed(或慢速 Java 正则表达式,如果您愿意) 用合理的列名替换这些虚线怪物。然后永远快乐。

    【讨论】:

    • 啊,顺便说一句:有不同的人开发 Hive 的不同部分。结果,CREATEALTER 命令的语义不一致(只需尝试运行“alter table SomeDB.SomeTable ...”看看会发生什么)。因此,CREATE 中支持的某些功能在 SELECT 中可能不起作用也就不足为奇了。
    • 向 serde 添加一个选项相当容易,例如在列名中使用下划线而不是句点,因此如果您创建一个包含“ORL_SOU_DH_SSTA10_T_HVAC_HeatLoad”列的表,它会查找“ORL.SOU.DH.SSTA10.T.HVAC.HeatLoad”。为什么不在 serde 的 github 中提出问题 - 我实际上是 serde 的创建者
    • @Samson Scharfrichter,我知道你提到的所有问题,但是 Hive 版本和 Json 数据已经被强加在这个项目中,所以我必须和他们一起去:( 我已经提出了在HDFS的存储数据中用下划线替换点,然后我对列名做了同样的事情。测试很好,但问题是原始数据被改变了,没有被项目接受。感谢您的支持!
    • @Roberto Congiu 非常感谢!如果解析器进行这种翻译,那就太好了。我现在就解决这个问题。
    • 只是推送更改来处理这个问题。见github.com/rcongiu/Hive-JSON-Serde#mapping-names-with-dots
    猜你喜欢
    • 2021-11-16
    • 2021-10-21
    • 1970-01-01
    • 2019-11-12
    • 1970-01-01
    • 2014-02-20
    • 1970-01-01
    • 1970-01-01
    • 2013-03-31
    相关资源
    最近更新 更多