3

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

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

任何解决此问题的帮助将不胜感激。

4

2 回答 2

1

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

于 2015-05-26T23:12:39.760 回答
1

是的,对此并不满意,但您似乎不太可能拥有那个确切的解决方案,特别是因为您的加入返回关系中将包含两个加入键(例如 - 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 表之前。

于 2015-12-10T20:15:55.490 回答