从 Pig 保存到 Hive 表的问题
Posted
技术标签:
【中文标题】从 Pig 保存到 Hive 表的问题【英文标题】:Issues saving to Hive table from Pig 【发布时间】:2014-12-05 19:18:06 【问题描述】:我正在使用HCatalog
从 Pig Script 向 Hive 读写数据,如下所示:
A = LOAD 'customer' USING org.apache.hcatalog.pig.HCatLoader();
B = LOAD 'address' USING org.apache.hcatalog.pig.HCatLoader();
C = JOIN A by cmr_id,B by cmr_id;
STORE C INTO 'cmr_address_join' USING org.apache.hcatalog.pig.HCatStorer();
customer 的表定义为:
cmr_id int
name string
地址:
addr_id int
cmr_id int
address string
cmr_address_join:
cmr_id int
name string
addr_id int
address string
当我运行它时,Pig 会抛出以下错误:
ERROR org.apache.pig.tools.grunt.Grunt - ERROR 1115: Column names should all be in lowercase. Invalid name found: A::cmr_id
我相信这可能是因为 Pig 试图将 Pig 生成的文件名与 Hive 列匹配,但它不完全匹配 (A::cmr_id versus cmr_id
)。我认为HCatalogStorer
期望别名是cmr_id
而不是A::cmr_id
。我希望HCatalogStorer
忽略别名前缀,只考虑字段名。
grunt> DESCRIBE C;
C: A::cmr_id: int,A::name: chararray,B::addr_id: int,B::cmr_id: int,B::address: chararray
有没有办法删除 Pig 中字段的前缀(即 A::)?或者,如果有人有解决方法或解决方案,那就太好了。
我知道我们可以使用以下内容显式添加别名并使其正常工作。
D = foreach C generate A::cmr_id as cmr_id,A::name as name, B::addr_id as addr_id, B::address as address;
STORE D INTO 'cmr_address_join' USING org.apache.hcatalog.pig.HCatStorer();
但我的问题是,我有很多表,每个表都有数百列。如上所述指定别名会变得乏味。
任何解决此问题的帮助将不胜感激。
【问题讨论】:
查看这个问题的解决方案。 ***.com/questions/38902046/… 【参考方案1】:您可以使用 $0、$1 等来访问列,请将它们重命名为列名,例如:$0 as cmr_id
【讨论】:
【参考方案2】:是的,这并不令人高兴,但您似乎不太可能拥有那个确切的解决方案,特别是因为您的连接返回关系将包含两个连接键(例如 - A::cmr_id 和 B:: cmr_id)。您已经找到了唯一真正的解决方案;用 FOREACH/GENERATE 适当地投影它并重命名列名。在实践中,您可能无论如何都必须对真正的 Hive 结构执行此操作,因为您不仅要正确命名列,而且要以正确的顺序排列列。更不用说“真正的”Hive 表不太可能将连接键的值存储两次。
我能想到的唯一其他解决方案(我不推荐)是将 C 作为 HDFS 上的文件存储,您有一个非托管(可能是外部)Hive 表配置为指向您刚刚的目录将文件存储到。您还可以预先创建一个 Hive 视图来预先创建该序列,可能会修剪额外的列(如重复的 cmr_id)、这些列,以便您可以使用 HCatLoader 执行新的 LOAD 命令,然后将该别名用于 HCatStorer STORE 命令。这在您的 Pig 脚本中可能看起来更好,但您仍然需要完成大部分工作(仅在 Hive 中),并且肯定会对性能产生影响,因为您必须先编写然后读取由表示的 HDFS 文件C 在将其保存到所需的 Hive 表之前。
【讨论】:
***.com/questions/38902046/…以上是关于从 Pig 保存到 Hive 表的问题的主要内容,如果未能解决你的问题,请参考以下文章