用于 PIG 捐赠错误的 Python UDF

Posted

技术标签:

【中文标题】用于 PIG 捐赠错误的 Python UDF【英文标题】:Python UDF for PIG Giving error 【发布时间】:2016-03-01 23:30:59 【问题描述】:

我有一个 Python UDF,可以将数据从十六进制转换为字符串。当我尝试在多个字段上调用 ​​UDF 时,出现错误。这是我的 Python UDF。脚本是 hex_to_str.py

#!/usr/bin/python

@outputSchema("field:chararray")
def hextoStr(field):
if(field!=""):
        return field.decode("hex")

我以下面的方式调用我的猪脚本。

register file:/home/myuser/myfolder/hex_to_str.py using jython as convert;
data = LOAD '/user/abc/hexfile' using PigStorage(',') as (Name:chararray, age:chararray);
hex = foreach data generate convert.hextoStr(Name),convert.hextoStr(age);
dump hex;

这是我在运行脚本时遇到的错误。

INFO  org.apache.pig.scripting.jython.JythonFunction - Schema 'field:chararray' defined for func hextoStr
ERROR org.apache.pig.tools.grunt.Grunt - ERROR 1108:
 <line 2, column 19> Duplicate schema alias: field

日志文件的Error也没有多说。

<line 2, column 19> Duplicate schema alias: field
        at org.apache.pig.newplan.logical.visitor.SchemaAliasVisitor.validate(SchemaAliasVisitor.java:75)
        at org.apache.pig.newplan.logical.visitor.SchemaAliasVisitor.visit(SchemaAliasVisitor.java:105)
        at org.apache.pig.newplan.logical.relational.LOGenerate.accept(LOGenerate.java:246)

但是,如果我只在一个字段上运行相同的脚本,那么它可以工作。

register file:/home/myuser/myfolder/hex_to_str.py using jython as convert;
data = LOAD '/user/abc/hexfile' using PigStorage(',') as (Name:chararray, age:chararray);
hex = foreach data generate Name,convert.hextoStr(age);
dump hex;

【问题讨论】:

【参考方案1】:

我怀疑这是因为@outputSchema("field:chararray") 装饰器指定了UDF 的名称(alias)和数据类型(默认情况下)。当您调用它两次时,您在 GENERATE 中使用了两次相同的别名,因此导致 Duplicate schema alias: field 错误。

您可以运行两个单独的GENERATEs,但我怀疑如果您重新别名,您将能够使用该函数两次。

例如,类似以下内容:

hex = foreach data generate convert.hextoStr(Name) as field1,convert.hextoStr(age) as field2;

然后每个结果将有自己的别名,并且该错误应该消失。如果不重新别名,Pig 将无法区分您在 GENERATE 语句的其他地方引用的结果。

回复 OP 的评论:

我怀疑你可以用你想要的任何特定字符串替换装饰器中的field,但是你仍然会遇到使用相同别名在两个不同字段上调用它两次的问题,所以你仍然需要重新-别名。我认为不可能在装饰器中使用变量,但是在 Pig 脚本中重新别名可以实现完全的动态性。例如您可以将它们别名为 agename 或类似名称以匹配实际字段名称。

有关Python UDFs 的更多详细信息,其中部分内容是:

示例模式字符串 - y:t:(word:chararray,num:long),变量名 架构字符串内部不会在任何地方使用,它们只是使 解析器可识别的语法。

【讨论】:

感谢您的回复。有什么方法可以在 @outputSchema("field:chararray") 处使用实际的 fieldName 到 UDF 中。例如,在我的情况下,有什么方法可以引用实际的字段名称(姓名或年龄)而不是字段 当然,没问题。我认为(从最终结果的角度来看),在 Pig 中重新混叠基本上可以满足您的要求。有关更多详细信息,请参阅上面我的答案中的编辑。您是否有特定原因不想在 Pig 脚本中重新命名? 没有具体原因,但我有一个包含 3000 多个字段的架构,我使用帮助脚本为此动态生成架构。在这种情况下,对我来说生成别名变得不那么困难了。如果我可以在 python UDF 中处理它,那么它就变得简单了。无论如何感谢您的帮助。 当然,没问题。有了这么多字段,我可以理解您希望 UDF 能够做到这一点。不幸的是,我认为目前不支持。

以上是关于用于 PIG 捐赠错误的 Python UDF的主要内容,如果未能解决你的问题,请参考以下文章

PIG UDF 错误 - 可以使用导入解决

在 Pig 中将关系传递给 Python UDF 时出错

在 Jython 的 Pig UDF 中导入外部库时出现错误 1121

在 pig 中使用 UDF 时出现错误 1070

在 Pig Latin 中加载 UDF 时发生 ClassCastException 错误

JAVA 错误 1070 中的 PIG UDF