在其他 pig 文件中导入公共常量声明的 pig 文件
Importing a common constant declared pig file in other pig files
Objective :在 constants.pig 中定义了常量(%declare 和 %default)语句以实现代码模块化并在其他 pig 文件中导入相同的语句.
根据文档:http://pig.apache.org/docs/r0.12.0/cont.html#import-macros,%declare 和 %default 是宏中的有效语句。
面临的问题:Pig 无法找到声明的参数。
猪文件:constants.pig
%declare ACTIVE_VALUES 'UK';
猪文件:a.pig
IMPORT 'constants.pig';
A = LOAD 'a.csv' using PigStorage(',') AS (country_code:chararray, country_name:chararray);
B = FILTER A BY country_code == '$ACTIVE_VALUES';
dump B;
输入:a.csv
IN,India
US,United States
UK,United Kingdom
错误
Error before Pig is launched
----------------------------
ERROR 2997: Encountered IOException. org.apache.pig.tools.parameters.ParameterSubstitutionException: Undefined parameter : ACTIVE_VALUES
java.io.IOException: org.apache.pig.tools.parameters.ParameterSubstitutionException: Undefined parameter : ACTIVE_VALUES
at org.apache.pig.impl.PigContext.doParamSubstitution(PigContext.java:414)
at org.apache.pig.Main.runParamPreprocessor(Main.java:810)
at org.apache.pig.Main.run(Main.java:588)
at org.apache.pig.Main.main(Main.java:170)
Caused by: org.apache.pig.tools.parameters.ParameterSubstitutionException: Undefined parameter : ACTIVE_VALUES
at org.apache.pig.tools.parameters.PreprocessorContext.substitute(PreprocessorContext.java:355)
at org.apache.pig.tools.parameters.PreprocessorContext.substitute(PreprocessorContext.java:303)
at org.apache.pig.tools.parameters.PigFileParser.input(PigFileParser.java:67)
at org.apache.pig.tools.parameters.PigFileParser.Parse(PigFileParser.java:43)
at org.apache.pig.tools.parameters.ParameterSubstitutionPreprocessor.parsePigFile(ParameterSubstitutionPreprocessor.java:95)
at org.apache.pig.tools.parameters.ParameterSubstitutionPreprocessor.genSubstitutedFile(ParameterSubstitutionPreprocessor.java:76)
at org.apache.pig.impl.PigContext.doParamSubstitution(PigContext.java:410)
... 3 more
我对 IMPORT 的理解是导入的 pig 的内容将被执行并可从调用 pig 脚本中获得。如果是这种情况,声明的参数应该在导入猪文件中可用。
任何关于拥有一个通用 pig 脚本文件的输入/想法,该文件将包含常量声明并将其导入其他 pig 文件以实现代码模块化。
更新:
已经就此提出了一个 JIRA 问题。参考下面的链接了解详情
IMPORT
关键字用于导入宏,而不是常量。 %declare
和 %default
是预处理器语句,其范围是脚本中的所有剩余行。如果您在脚本中声明它,但从另一个脚本中导入它,它将不起作用,因为它超出了范围。
这两个语句在宏中都是有效的,只要你在宏中使用声明的变量。如果您需要在脚本之外定义常量以实现模块化,则需要使用 parameter file:
ACTIVE_VALUES = 'UK'
然后 运行 您的 Pig 脚本如下所示:
pig -param_file your_params_file.properties -f your_script.pig
如果你真的想使用 IMPORT
,你可以创建一个宏来处理具有该常量值的过滤:
%declare ACTIVE_VALUES 'UK';
DEFINE my_custom_filter(A) RETURNS B {
$B = FILTER $A BY [=12=] == '$ACTIVE_VALUES ';
};
然后像在脚本中一样导入它,但不是调用 FILTER
函数,而是调用您自己的宏:
IMPORT 'macro.pig';
A = LOAD 'a.csv' using PigStorage(',') AS (country_code:chararray, country_name:chararray);
B = my_custom_filter(A);
dump B;
虽然有点老套,但另一种可能的解决方案是使用 python 控制器,并在该 python 控制器中连接两个文件。您可以阅读有关控制器的信息 here。
这可能是它的样子,并且对您当前的结构的破坏最小:
#!/usr/bin/python
from org.apache.pig.scripting import Pig
def readfile(f):
out = []
with open(f, 'r') as infile:
for line in infile:
out.append(file)
return out
constants = readfile('constants.pig')
script = readfile('a.pig')
# Compile
P = Pig.compile('\n'.join(constants + scripts))
# Run
result = P.bind({}).runSingle()
但是,您也可以尝试将要更改的变量传入作为 bind
方法参数的字典中。这与使用 parameter substitution 的过程相同,我建议这样做。
Objective :在 constants.pig 中定义了常量(%declare 和 %default)语句以实现代码模块化并在其他 pig 文件中导入相同的语句.
根据文档:http://pig.apache.org/docs/r0.12.0/cont.html#import-macros,%declare 和 %default 是宏中的有效语句。
面临的问题:Pig 无法找到声明的参数。
猪文件:constants.pig
%declare ACTIVE_VALUES 'UK';
猪文件:a.pig
IMPORT 'constants.pig';
A = LOAD 'a.csv' using PigStorage(',') AS (country_code:chararray, country_name:chararray);
B = FILTER A BY country_code == '$ACTIVE_VALUES';
dump B;
输入:a.csv
IN,India
US,United States
UK,United Kingdom
错误
Error before Pig is launched
----------------------------
ERROR 2997: Encountered IOException. org.apache.pig.tools.parameters.ParameterSubstitutionException: Undefined parameter : ACTIVE_VALUES
java.io.IOException: org.apache.pig.tools.parameters.ParameterSubstitutionException: Undefined parameter : ACTIVE_VALUES
at org.apache.pig.impl.PigContext.doParamSubstitution(PigContext.java:414)
at org.apache.pig.Main.runParamPreprocessor(Main.java:810)
at org.apache.pig.Main.run(Main.java:588)
at org.apache.pig.Main.main(Main.java:170)
Caused by: org.apache.pig.tools.parameters.ParameterSubstitutionException: Undefined parameter : ACTIVE_VALUES
at org.apache.pig.tools.parameters.PreprocessorContext.substitute(PreprocessorContext.java:355)
at org.apache.pig.tools.parameters.PreprocessorContext.substitute(PreprocessorContext.java:303)
at org.apache.pig.tools.parameters.PigFileParser.input(PigFileParser.java:67)
at org.apache.pig.tools.parameters.PigFileParser.Parse(PigFileParser.java:43)
at org.apache.pig.tools.parameters.ParameterSubstitutionPreprocessor.parsePigFile(ParameterSubstitutionPreprocessor.java:95)
at org.apache.pig.tools.parameters.ParameterSubstitutionPreprocessor.genSubstitutedFile(ParameterSubstitutionPreprocessor.java:76)
at org.apache.pig.impl.PigContext.doParamSubstitution(PigContext.java:410)
... 3 more
我对 IMPORT 的理解是导入的 pig 的内容将被执行并可从调用 pig 脚本中获得。如果是这种情况,声明的参数应该在导入猪文件中可用。
任何关于拥有一个通用 pig 脚本文件的输入/想法,该文件将包含常量声明并将其导入其他 pig 文件以实现代码模块化。
更新:
已经就此提出了一个 JIRA 问题。参考下面的链接了解详情
IMPORT
关键字用于导入宏,而不是常量。 %declare
和 %default
是预处理器语句,其范围是脚本中的所有剩余行。如果您在脚本中声明它,但从另一个脚本中导入它,它将不起作用,因为它超出了范围。
这两个语句在宏中都是有效的,只要你在宏中使用声明的变量。如果您需要在脚本之外定义常量以实现模块化,则需要使用 parameter file:
ACTIVE_VALUES = 'UK'
然后 运行 您的 Pig 脚本如下所示:
pig -param_file your_params_file.properties -f your_script.pig
如果你真的想使用 IMPORT
,你可以创建一个宏来处理具有该常量值的过滤:
%declare ACTIVE_VALUES 'UK';
DEFINE my_custom_filter(A) RETURNS B {
$B = FILTER $A BY [=12=] == '$ACTIVE_VALUES ';
};
然后像在脚本中一样导入它,但不是调用 FILTER
函数,而是调用您自己的宏:
IMPORT 'macro.pig';
A = LOAD 'a.csv' using PigStorage(',') AS (country_code:chararray, country_name:chararray);
B = my_custom_filter(A);
dump B;
虽然有点老套,但另一种可能的解决方案是使用 python 控制器,并在该 python 控制器中连接两个文件。您可以阅读有关控制器的信息 here。
这可能是它的样子,并且对您当前的结构的破坏最小:
#!/usr/bin/python
from org.apache.pig.scripting import Pig
def readfile(f):
out = []
with open(f, 'r') as infile:
for line in infile:
out.append(file)
return out
constants = readfile('constants.pig')
script = readfile('a.pig')
# Compile
P = Pig.compile('\n'.join(constants + scripts))
# Run
result = P.bind({}).runSingle()
但是,您也可以尝试将要更改的变量传入作为 bind
方法参数的字典中。这与使用 parameter substitution 的过程相同,我建议这样做。