【问题标题】:Google Dataflow - Failed to import custom python modulesGoogle Dataflow - 无法导入自定义 python 模块
【发布时间】:2018-07-10 09:45:49
【问题描述】:

我的 Apache 光束管道实现了自定义转换和 ParDo 的 python 模块,这些模块进一步导入了我编写的其他模块。在本地运行器上,这工作正常,因为所有可用文件都在同一路径中可用。在 Dataflow 运行器的情况下,管道会因模块导入错误而失败。

如何使自定义模块可供所有数据流工作人员使用?请指教。

下面是一个例子:

ImportError: No module named DataAggregation

    at find_class (/usr/lib/python2.7/pickle.py:1130)
    at find_class (/usr/local/lib/python2.7/dist-packages/dill/dill.py:423)
    at load_global (/usr/lib/python2.7/pickle.py:1096)
    at load (/usr/lib/python2.7/pickle.py:864)
    at load (/usr/local/lib/python2.7/dist-packages/dill/dill.py:266)
    at loads (/usr/local/lib/python2.7/dist-packages/dill/dill.py:277)
    at loads (/usr/local/lib/python2.7/dist-packages/apache_beam/internal/pickler.py:232)
    at apache_beam.runners.worker.operations.PGBKCVOperation.__init__ (operations.py:508)
    at apache_beam.runners.worker.operations.create_pgbk_op (operations.py:452)
    at apache_beam.runners.worker.operations.create_operation (operations.py:613)
    at create_operation (/usr/local/lib/python2.7/dist-packages/dataflow_worker/executor.py:104)
    at execute (/usr/local/lib/python2.7/dist-packages/dataflow_worker/executor.py:130)
    at do_work (/usr/local/lib/python2.7/dist-packages/dataflow_worker/batchworker.py:642)

【问题讨论】:

    标签: python google-cloud-dataflow apache-beam


    【解决方案1】:

    问题可能是您没有将文件分组为一个包。 Beam 文档上有a section

    多文件依赖

    通常,您的管道代码跨越多个文件。要远程运行您的项目,您必须将这些文件分组为 Python 包,并在运行管道时指定该包。当远程工作人员启动时,他们将安装您的软件包。要将文件分组为 Python 包并使其远程可用,请执行以下步骤:

    1. 为您的项目创建一个setup.py 文件。下面是一个很基础的setup.py文件。

      setuptools.setup(
          name='PACKAGE-NAME'
          version='PACKAGE-VERSION',
          install_requires=[],
          packages=setuptools.find_packages(),
      )
      
    2. 构建您的项目,使根目录包含setup.py 文件、主工作流文件以及包含其余文件的目录。

      root_dir/
          setup.py
          main.py
          other_files_dir/
      

    请参阅Juliaset,了解遵循此所需项目结构的示例。

    1. 使用以下命令行选项运行您的管道:

      --setup_file /path/to/setup.py
      

    注意: 如果您创建了一个 requirements.txt 文件并且您的项目跨越多个文件,您可以去掉 requirements.txt 文件,而是将 requirements.txt 中包含的所有包添加到安装调用的 install_requires 字段(在步骤 1 中)。

    【讨论】:

    • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review
    • 这很有意义。我用相关部分的引用更新了答案,因为该部分的说明没有太多可浓缩的内容。
    • 值得注意的是setup.py 文件与您运行最终python 命令的目录相同,那么您必须在其前面添加./--setup_file ./setup.py
    【解决方案2】:

    我遇到了同样的问题,不幸的是,文档并不像他们需要的那样冗长。 因此,问题在于root_dirother_files_dir 都必须包含__init__.py 文件。当一个目录包含__init__.py 文件(即使它是空的)时,python 会将该目录视为一个包,在这种情况下,这就是我们想要的。因此,您的最终文件夹结构应如下所示:

    root_dir/
        __init__.py
        setup.py
        main.py
        other_files_dir/
            __init__.py
            module_1.py
            module_2.py
    

    您会发现,python 将构建一个 .egg-info 文件夹,该文件夹描述您的包,包括所有 pip 依赖项。它还将包含top_level.txt 文件,其中包含保存模块的目录的名称(即other_files_dir

    然后您只需调用main.py 中的模块,如下所示

    from other_files_dir import module_1
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-20
      • 1970-01-01
      • 2023-03-10
      • 2012-02-24
      • 1970-01-01
      相关资源
      最近更新 更多