当在Oozie中运行Python脚本时,我该如何导入本地Python模块?

3
我有两个Python文件 - my_python_A.py和my_python_B.py。第一个文件引用了第二个文件(from my_python_B import *)。
我在Oozie的shell操作中执行第一个Python文件(即脚本只是python my_python_A.py),并收到以下错误:
Traceback (most recent call last):
  File "my_python_A.py", line 2, in <module>
    from my_python_B import *
ImportError: No module named my_python_B
Failing Oozie Launcher, Main class [org.apache.oozie.action.hadoop.ShellMain], exit code [1]

这两个Python文件都位于HDFS中的同一目录下。我该如何让这个导入语句起作用?


通常情况下,解释器首先查找“当前目录”,然后查找您的“shell”,最后查找您的“默认路径”。您使用哪个环境?这些文件是否属于同一项目?如果是,则最好使用一个“__init__”文件。 - mugabits
明白了。我对Oozie不太熟悉,但听起来你的解释器无法识别你的模块,所以你可以尝试将工作目录添加到你的shell路径中。 - mugabits
请查看此答案 - mugabits
你可以尝试类似于import sys sys.path.append("/Users/path/to/file")的代码。 - jkhadka
@SamsonScharfrichter - 我们实际上已经尝试过了。我们检查了,Oozie已经将它们部署到同一个文件夹中,但是导入语句没有起作用。 - John
显示剩余2条评论
2个回答

7

我遇到过同样的问题,解决方法是在执行Python代码之前,在Shell脚本中将环境变量PYTHONPATH设置为当前工作目录。

export PYTHONPATH=`pwd`
python m_python_A.py

请确保在您的shell操作中,已经将所有需要的Python模块包含在<file></file>标签内。假设您有一个名为sample_script.sh的shell脚本(其中包含上述命令),则您的workflow.xml文件应该类似于以下内容:

<workflow-app name="shellTest" xmlns="uri:oozie:workflow:0.4">
    <start to="shell-action"/>
    <action name="shell-action">
        <shell xmlns="uri:oozie:shell-action:0.2">
            <job-tracker>${jobTracker}</job-tracker>
            <name-node>${nameNode}</name-node>
            <configuration>                
                <property>
                    <name>oozie.launcher.mapred.job.queue.name</name>
                    <value>${launcherqueue}</value>
                </property>
                <property>
                    <name>mapred.job.queue.name</name>
                    <value>${mapredqueue}</value>
                </property>
            </configuration>
            <exec>sample_script.sh</exec>
            <file>${appPath}/sample_script.sh#sample_script.sh</file>
            <file>${appPath}/m_python_A.py#m_python_A.py</file>
            <file>${appPath}/m_python_B.py#m_python_B.py</file>
            <capture-output/>
        </shell>
        <ok to="end"/>
        <error to="shell-action-failed"/>
    </action>

    <kill name="shell-action-failed">
        <message>Shell action failed, error message[${wf:errorMessage(wf:lastErrorNode())}]</message>
    </kill>

    <end name="end" />

</workflow-app>

在你的例子中,${appPath}是什么? - Milimetric
${appPath} 是 HDFS 上存放你的脚本的文件夹路径。 - Nitin Kumar

1

添加什么?

sys.path.append(os.path.join(os.path.dirname(__file__), "lib"))

在你的m_python_A.py中访问存储在lib/中的任何内容,该怎么做?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接