如何根据相对路径导入Python模块?
例如,如果dirFoo包含Foo.py和dirBar,和dirBar包含Bar.py,我怎么导入Bar.py到Foo.py?
这是一个直观的表示:
dirFoo\
Foo.py
dirBar\
Bar.py
Run Code Online (Sandbox Code Playgroud)
Foo希望包括Bar,但重组文件夹层次结构不是一种选择.
我构建了一个python模块,我想在我的pyspark应用程序中导入它.
我的包目录结构是:
wesam/
|-- data.py
`-- __init__.py
Run Code Online (Sandbox Code Playgroud)
import wesam我的pyspark脚本顶部的一个简单导致ImportError: No module named wesam.我也试图压缩它与我的代码以出货--py-files为推荐这个答案,没有运气.
./bin/spark-submit --py-files wesam.zip mycode.py
Run Code Online (Sandbox Code Playgroud)
我也按照这个答案的建议以编程方式添加了文件,但是我得到了同样的ImportError: No module named wesam错误.
.sc.addPyFile("wesam.zip")
Run Code Online (Sandbox Code Playgroud)
我在这里错过了什么?
我知道您可以使用Python Spark程序将各个文件作为依赖项发送.但是完全成熟的图书馆(例如numpy)呢?
Spark是否有办法使用提供的包管理器(例如pip)来安装库依赖项?或者这是否必须在执行Spark程序之前手动完成?
如果答案是手动的,那么在大量分布式节点上同步库(安装路径,版本等)的"最佳实践"方法是什么?
dependencies hadoop distributed-computing shared-libraries apache-spark
使用addPyFiles()似乎不是添加desiered文件来激发作业节点(新兴的火花因此可能缺少一些基本的使用知识).
尝试使用pyspark运行脚本,并且发现导致某些模块未找到导致的错误.从未使用过火花,但其他帖子(来自问题包https://github.com/cerndb/dist-keras/issues/36#issuecomment-378918484和/sf/answers/2784549001/)推荐压缩模块并通过添加到spark作业sparkContext.addPyFiles(mymodulefiles.zip),但仍然出现错误.相关的代码片段是......
from distkeras.trainers import *
from distkeras.predictors import *
from distkeras.transformers import *
from distkeras.evaluators import *
from distkeras.utils import *
Run Code Online (Sandbox Code Playgroud)
(我在这里导入的包可以在https://github.com/cerndb/dist-keras找到),
conf = SparkConf()
conf.set("spark.app.name", application_name)
conf.set("spark.master", master) #master='yarn-client'
conf.set("spark.executor.cores", `num_cores`)
conf.set("spark.executor.instances", `num_executors`)
conf.set("spark.locality.wait", "0")
conf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer");
if using_spark_2:
from pyspark.sql import SparkSession
sc = SparkSession.builder.config(conf=conf) \
.appName(application_name) \
.getOrCreate()
sc.sparkContext.addPyFile("/home/me/Downloads/distkeras.zip") # see https://github.com/cerndb/dist-keras/issues/36#issuecomment-378918484 and https://forums.databricks.com/answers/10207/view.html
print sc.version
Run Code Online (Sandbox Code Playgroud)
(distkeras.zip是这个目录的压缩文件:https://github.com/cerndb/dist-keras/tree/master/distkeras),以及
transformer = OneHotTransformer(output_dim=nb_classes, input_col="label_index", output_col="label") …Run Code Online (Sandbox Code Playgroud) 我正在尝试运行依赖于某些python3库的PySpark作业.我知道我可以在Spark Cluster上安装这些库,但由于我正在重新使用群集进行多个作业,我想将所有依赖项捆绑在一起并通过--py-files指令将它们传递给每个作业.
为此,我使用:
pip3 install -r requirements.txt --target ./build/dependencies
cd ./build/dependencies
zip -qrm . ../dependencies.zip
Run Code Online (Sandbox Code Playgroud)
这有效地压缩了在根级别使用的所需包中的所有代码.
在我,main.py我可以导入依赖项
if os.path.exists('dependencies.zip'):
sys.path.insert(0, 'dependencies.zip')
Run Code Online (Sandbox Code Playgroud)
并将.zip添加到我的Spark上下文中
sc.addPyFile('dependencies.zip')
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.
但出于某种原因,这将在Spark Cluster上转移到某种依赖地狱
比如跑步
spark-submit --py-files dependencies.zip main.py
在main.py(或类)我想要使用熊猫的地方.它将触发此错误的代码:
Traceback(最近一次调用最后一次):
在job_module = importlib.import_module('spark.jobs.%s'%args.job_name)中输入文件"/Users/tomlous/Development/Python/enrichers/build/main.py",第53行...
文件"",第978行,在_gcd_import中
文件"",第961行,在_find_and_load中
文件"",第950行,在_find_and_load_unlocked中
文件"",第646行,在_load_unlocked中
文件"",第616行,在_load_backward_compatible中
文件"dependencies.zip/spark/jobs/classify_existence.py",第9行,in
文件"dependencies.zip/enrich/existence.py",第3行,in
文件"dependencies.zip/pandas/ 初始化 py"为19行,在
ImportError:缺少必需的依赖项['numpy']
看着熊猫,__init__.py 我看到了类似的东西__import__(numpy)
所以我认为numpy没有加载.
但是,如果我改变我的代码以显式调用numpy函数,它实际上发现numpy,但不是它的一些dependecies
import numpy as np
a = np.array([1, 2, 3])
Run Code Online (Sandbox Code Playgroud)
代码返回
Traceback(最近一次调用最后一次):
文件"dependencies.zip/numpy/core/ 初始化的.py",第16行,在
ImportError:无法导入名称'multiarray'
所以我的问题是:
我应该如何将python3库与我的spark作业捆绑在一起,以便我不必在Spark集群上安装所有可能的库?
我有一些想要在应用程序中使用的自定义 jdbc 驱动程序。当我将 Spark 提交到 Kubernetes Spark 集群时,我将这些包含为 --py-files:
spark-submit --py-files s3a://bucket/pyfiles/pyspark_jdbc.zip my_application.py
Run Code Online (Sandbox Code Playgroud)
这给了我:
java.io.FileNotFoundException: File file:/opt/spark/work-dir/pyspark_jdbc.zip does not exist
Run Code Online (Sandbox Code Playgroud)
正如其他答案告诉我的那样,我实际上需要将该 zip 文件添加到 PYTHONPATH 中。现在,我发现至少在 Spark 2.3+ 中不再如此,但让我们这样做:
spark.sparkContext.addPyFile("pyspark_jdbc.zip")
Run Code Online (Sandbox Code Playgroud)
查看集群日志,我看到:
19/10/21 22:40:56 INFO Utils: Fetching s3a://bucket/pyfiles/pyspark_jdbc.zip to
/var/data/spark-52e390f5-85f4-41c4-9957-ff79f1433f64/spark-402e0a00-6806-40a7-a17d-5adf39a5c2d4/userFiles-680c1bce-ad5f-4a0b-9160-2c3037eefc29/fetchFileTemp5609787392859819321.tmp
Run Code Online (Sandbox Code Playgroud)
因此,pyfiles 肯定被导入,但导入/var/data/...而不是导入我的工作目录。因此,当我将 .zip 文件的位置添加到 python 路径时,我不知道它在哪里。在尝试添加 python 文件之前对集群进行一些诊断:
> print(sys.path)
[...,
'/var/data/spark-52e390f5-85f4-41c4-9957-ff79f1433f64/spark-402e0a00-6806-40a7-a17d-5adf39a5c2d4/userFiles-680c1bce-ad5f-4a0b-9160-2c3037eefc29',
'/opt/spark/work-dir/s3a',
'//bucket/pyfiles/pyspark_jdbc.zip'
...]
> print(os.getcwd())
/opt/spark/work-dir
> subprocess.run(["ls", "-l"])
total 0
Run Code Online (Sandbox Code Playgroud)
所以我们看到 pyspark 确实尝试将s3a://我通过--py-filesPYTHONPATH 添加的文件添加到 PYTHONPATH 中,只是它错误地解释了:并且没有正确添加路径。该/var/data/...目录位于 PYTHONPATH …
apache-spark ×5
pyspark ×4
python ×3
dependencies ×1
hadoop ×1
import ×1
numpy ×1
python-3.x ×1