我正在尝试使用 Flex 模板运行 Dataflow 作业,但我遇到了“未找到模块错误”,我无法弄清楚原因,所以这里是我的目录结构
|__ modules |____ edgar_quarterly_form4.py |____ __init__.py |__ main.py |__ setup.py |__ __init__.py
我的 main.py 代码中有这个导入
from modules import edgar_quarterly_form4
这是我的dockerfile
FROM gcr.io/dataflow-templates-base/python3-template-launcher-base ARG WORKDIR=/dataflow/template RUN mkdir -p ${WORKDIR} RUN mkdir -p ${WORKDIR}/modules WORKDIR ${WORKDIR} COPY spec/python_command_spec.json ${WORKDIR}/python_command_spec.json COPY modules ${WORKDIR}/modules ENV DATAFLOW_PYTHON_COMMAND_SPEC ${WORKDIR}/python_command_spec.json RUN pip install avro-python3 pyarrow==0.15.1 apache-beam[gcp]==2.27.0 COPY __init__.py ${WORKDIR}/__init__.py COPY setup.py ${WORKDIR}/setup.py COPY main.py ${WORKDIR}/main.py # Super important to add these lines. ENV FLEX_TEMPLATE_PYTHON_SETUP_FILE="${WORKDIR}/setup.py" ENV FLEX_TEMPLATE_PYTHON_PY_FILE="${WORKDIR}/main.py"
这是我的 setup.py 文件
import setuptools REQUIRED_PACKAGES = [ 'numpy', 'beautifulsoup4', 'pandas', 'sendgrid==6.2.1', 'lxml', 'pandas_datareader', 'apache-beam[gcp]==2.27.0', ] setuptools.setup( packages=setuptools.find_packages(), install_requires=REQUIRED_PACKAGES, )
但是,每次运行我的模板时都会出现此错误
368, in load_session module = unpickler.load() File "/usr/local/lib/python3.7/site- packages/dill/_dill.py", line 472, in load obj = StockUnpickler.load(self) File "/usr/local/lib/python3.7/site-packages/dill/_dill.py", line 827, in _import_module return getattr(__import__(module, None, None, [obj]), obj) ModuleNotFoundError: No module named 'modules'
我不知道为什么。我向我的 docker 文件添加了一些 echo 来查看是否已复制所有文件,并且所有文件都已成功复制到映像中…所以我真的不知道发生了什么。请注意,即使 edgar_quarterly_form4.py 文件与 main.py 位于同一目录中,我也会收到完全相同的错误
从你的描述和提供的代码来看,ModuleNotFoundError: No module named 'modules' 的原因可能与 Python 的包结构、PYTHONPATH 环境变量设置、或 setup.py 的配置不正确有关。以下是可能的原因及解决方法:
ModuleNotFoundError: No module named 'modules'
PYTHONPATH
setup.py
你的 setup.py 文件可能没有正确地将 modules 目录识别为一个包。
modules
__init__.py
setuptools.setup( name='my_dataflow_package', version='0.1', packages=setuptools.find_packages(include=["modules", "modules.*"]), install_requires=REQUIRED_PACKAGES, )
运行 Dataflow 作业时,Python 可能无法正确识别 modules 包的路径。
在 Dockerfile 中设置 PYTHONPATH: dockerfile ENV PYTHONPATH="${WORKDIR}:${WORKDIR}/modules" 这确保了 Python 在运行时能够找到 modules 目录。
dockerfile ENV PYTHONPATH="${WORKDIR}:${WORKDIR}/modules"
验证容器内部是否正确设置了路径: 在构建的镜像中执行: sh python -c "import sys; print(sys.path)" 检查是否包含 ${WORKDIR} 和 ${WORKDIR}/modules。
sh python -c "import sys; print(sys.path)"
${WORKDIR}
${WORKDIR}/modules
Flex Template 使用的 Dataflow 容器可能没有正确安装你的 Python 包。
确保在 Dockerfile 中添加了以下命令以安装你的包: dockerfile RUN pip install . 这会根据你的 setup.py 安装所有依赖项及自定义模块。
dockerfile RUN pip install .
确认镜像中安装了你的模块: 在构建的镜像中运行以下命令: sh python -m pip list 检查是否包含 modules 包。
sh python -m pip list
Dataflow 的 apache_beam 使用序列化来传递代码和数据。如果你使用的模块未正确序列化,可能会导致 ModuleNotFoundError。
apache_beam
ModuleNotFoundError
apache_beam.transforms.util
AsSource
AsSink
main.py
完成修改后,请重新构建镜像并测试: 1. 清理旧镜像: bash docker rmi <image_name> 2. 重新构建: bash docker build -t <image_name> . 3. 验证模块是否正常运行: bash docker run -it <image_name> python main.py
bash docker rmi <image_name>
bash docker build -t <image_name> .
bash docker run -it <image_name> python main.py
如果仍然出现错误,请提供你执行的具体命令和任何额外的日志,我可以进一步帮助你。