从Pig保存到Hive表的问题

时间:2014-12-05 19:18:07

标签: hive apache-pig alias hcatalog

我正在使用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();

客户的表格定义为:

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();

但我的问题是,我有很多表,每个表都有数百列。如上所述指定别名将变得乏味。

任何帮助解决这个问题都将非常感激。

2 个答案:

答案 0 :(得分:1)

您可以使用$ 0,$ 1等来访问列,请将它们重命名为列名,例如:$ 0 as cmr_id

答案 1 :(得分:1)

是的,这个没有任何乐趣,但你似乎不太可能有这个确切的解决方案,特别是因为你的join-returned关系将包含两个连接键(例如 - A :: cmr_id和B :: cmr_id)。你已经找到了唯一真正的解决方案;使用FOREACH / GENERATE对其进行适当的投影并重命名列名。在实践中,您可能必须为真正的Hive结构执行此操作,因为您必须使列不仅正确命名,而是以正确的顺序。更不用说“真正的”Hive表不太可能将连接键的值存储两次。

我能想到的唯一其他解决方案(我不推荐)将存储C作为HDFS上的文件,你有一个非托管(可能是EXTERNAL)Hive表,配置为指向你刚才的目录将文件存入。您还可以预先创建一个Hive视图来创建序列,可能修剪额外的列(如重复的cmr_id),列,以便您可以使用HCatLoader执行新的LOAD命令,然后将该别名用于HCatStorer STORE命令。这可能在你的Pig脚本中看起来更好,但是你仍然需要完成大部分工作(仅在Hive中)并且肯定会对性能产生影响,因为你必须编写,然后读取由表示的HDFS文件。 C之前将其保存到所需的Hive表中。