Pig:无法使用 PigStorage 加载数据

Posted

技术标签:

【中文标题】Pig:无法使用 PigStorage 加载数据【英文标题】:Pig: Unable to load data using PigStorage 【发布时间】:2015-02-02 02:01:19 【问题描述】:

我在 txt 文件中有这个小数据集(格式:名字、姓氏、年龄、性别)

(Eric,Ack,27,M),(Jeremy,Ross,29,F)
(Jenny,Dicken,27,F),(Vijay,Sampath,40,M)
(Angs,Dicken,28,M),(Venu,Rao,28,M)
(Mahima,Mohanty,29,F),(Kenny,Oath,28,M)

我正在尝试像这样加载这些数据:

tuple_record = LOAD '~/Documents/Pig_Tuple.txt' USING PigStorage(',') AS (details:tuple(firstname:chararray,lastname:chararray,age:int,sex:chararray));

但这不起作用:

DUMP tuple_record;

我在运行这个命令时得到了这个(即它什么都不返回)

()
()
()
()

请告知如何加载此数据集。

【问题讨论】:

【参考方案1】:

原因是,元组内的tupleeach fields 都有same delimiter(',')。在这种情况下,pig 将解析输入并在模式转换中失败。

您可以在控制台中看到以下日志

"Unable to interpret the value in field being converted to type tuple, caught ParseException <Unexpect end of tuple> field discarded"

解决此问题

    您需要将元组分隔符 ',' 更改为不同的值。在下面的示例中,我使用'#' 作为分隔符而不是','。您可以使用除 (',') 以外的任何分隔符

    您的输入文件有两个元组,但您在加载模式中只定义了一个元组,因此您还需要定义另一个。

示例:

输入

(Eric,Ack,27,M)#(Jeremy,Ross,29,F)
(Jenny,Dicken,27,F)#(Vijay,Sampath,40,M)
(Angs,Dicken,28,M)#(Venu,Rao,28,M)
(Mahima,Mohanty,29,F)#(Kenny,Oath,28,M)

Pigscript:

tuple_record = LOAD '~/Documents/Pig_Tuple.txt' USING PigStorage('#') AS (details:tuple(firstname:chararray,lastname:chararray,age:int,sex:chararray), details1:tuple(firstname1:chararray,lastname1:chararray,age1:int,sex1:chararray));
DUMP tuple_record;

输出:

((Eric,Ack,27,M),(Jeremy,Ross,29,F))
((Jenny,Dicken,27,F),(Vijay,Sampath,40,M))
((Angs,Dicken,28,M),(Venu,Rao,28,M))
((Mahima,Mohanty,29,F),(Kenny,Oath,28,M))

更新:如何将分隔符 ',' 更改为不同的东西选项 1:使用 sed 这是一个非常简单的选项,通过使用 sed 命令将'),(' 模式替换为')#(' 模式,这样在同一个输入文件中分隔符将从',' 更改为'#'。(注意:备份您的在执行这个 sed 脚本之前输入文件)

>> sed -i -- 's/),(/)#(/g' inputFile

选项 2:在 pigscript 中稍作修改而不更改分隔符Pigscript:

--Read each input line as chararray
A = LOAD 'inputFile' AS (line:chararray);

--Remove the character '(',')' from the input
B = FOREACH A GENERATE FLATTEN(REPLACE(line,'[)(]+','')) AS (newline:chararray);

--Split the input using ',' as delimiter, 8 refer to total number of fields
C = FOREACH B GENERATE FLATTEN(STRSPLIT(newline,',',8)) AS (firstname1:chararray,lastname1:chararray,age1:int,sex1:chararray,firstname2:chararray,lastname2:chararray,age2:int,sex2:chararray);

--Group the fields and form tuples 
D = FOREACH C GENERATE TOTUPLE(firstname1,lastname1,age1,sex1) AS details1,TOTUPLE(firstname2,lastname2,age2,sex2) AS details2;

--Now you can do whatever you want.
E = FOREACH D GENERATE details1.firstname1,details2.firstname2;
DUMP E;

【讨论】:

对如何更改输入文件的分隔符有什么建议吗?请建议 一个选项可能是您可以使用 STORE 命令更改分隔符格式。 pig.apache.org/docs/r0.13.0/basic.html#store。如果您需要任何帮助,请告诉我。 本例中,先加载数据,再用改变的分隔符存储;但在我的情况下,加载本身会导致问题。请帮忙。 好的,知道了。我在帖子中更新了两个解决方案。请检查一下。【参考方案2】:

请查看Pig Documentation的复杂方案部分

cat data;
(3,8,9) (mary,19)
(1,4,7) (john,18)
(2,5,8) (joe,18)

A = LOAD data AS (F:tuple(f1:int,f2:int,f3:int),T:tuple(t1:chararray,t2:int));

DESCRIBE A;
A: F: (f1: int,f2: int,f3: int),T: (t1: chararray,t2: int)

DUMP A;
((3,8,9),(mary,19))
((1,4,7),(john,18))
((2,5,8),(joe,18))

【讨论】:

以上是关于Pig:无法使用 PigStorage 加载数据的主要内容,如果未能解决你的问题,请参考以下文章

使用'-tagFile'选项的项目文件名字段,使用PigStorage'-tagFile'加载,Pig 0.14

使用 PigStorage 加载缺少最后一个字段的数据

Pig 读取数据作为 databytearray

在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?

Apache PIG:pigstorage 不添加扩展

在 PIG 中加载 CSV 文件