Python 包装DAG-气流罐';找不到已安装的模块

Python 包装DAG-气流罐';找不到已安装的模块,python,airflow,Python,Airflow,我正在尝试将apacheairlfow与打包的dag()一起使用 我的代码是以python包的形式编写的,显然我的代码依赖于其他流行的库,如numpy、scipy等 编辑: 这是我的自定义python包的setup.py: from setuptools import setup, find_packages from pathlib import Path from typing import List import distutils.text_file def parse_requir

我正在尝试将apacheairlfow与打包的dag()一起使用

我的代码是以python包的形式编写的,显然我的代码依赖于其他流行的库,如numpy、scipy等

编辑: 这是我的自定义python包的
setup.py

from setuptools import setup, find_packages
from pathlib import Path
from typing import List

import distutils.text_file

def parse_requirements(filename: str) -> List[str]:
    """Return requirements from requirements file."""
    # Ref: https://stackoverflow.com/a/42033122/
    return distutils.text_file.TextFile(filename=str(Path(__file__).with_name(filename))).readlines()


setup(name='classify_business',
      version='0.1',
      python_requires=">=3.6",
      description='desc',
      url='https://urlgitlab/datascience/classifybusiness',
      author='Marco fumagalli',
      author_email='marco.fumagalli@mycompany.com',
      packages = find_packages(),
      license='MIT',
      install_requires=
      parse_requirements('requirements.txt'),
      zip_safe=False,
      include_package_data=True)
requirements.txt包含我的代码所需的软件包(vertica_python、pandas、numpy等)及其版本

我根据文档中提供的脚本编写了一个小shell脚本:

set -eu -o pipefail

if [ $# == 0 ]; then
    echo "First param should be /srv/user_name/virtualenvs/name_virtual_env"
    echo "Second param should be name of temp_directory"
    echo "Third param directory should be git url"
    echo "Fourth param should be dag zip name, i.e dag_zip.zip to be copied into AIRFLOW__CORE__DAGS__FOLDER"
    echo "Fifth param should be package name, i.e classify_business"
fi


venv_path=${1}
dir_tmp=${2}
git_url=${3}
dag_zip=${4}
pkg_name=${5}



python3 -m venv $venv_path
source $venv_path/bin/activate
mkdir $dir_tmp
cd $dir_tmp

python3 -m pip install --prefix=$PWD git+$git_url

zip -r $dag_zip *
cp $dag_zip $AIRFLOW__CORE__DAGS_FOLDER

rm -r $dir_tmp
shell将直接从gitlab、zip安装我的包和依赖项,然后移动到dags文件夹

这是压缩前文件夹tmp_dir的内容

bin  
lib  
lib64  
predict_dag.py  
train_dag.py
Airflow似乎无法导入安装在lib或lib64中的包。 我犯了这个错误

ModuleNotFoundError:没有名为“vertica_python”的模块

我甚至尝试将我的自定义包移到lib之外:

bin
my_custom_package
lib  
lib64  
predict_dag.py  
train_dag.py
但仍然得到同样的错误

PS:我认为问题之一在于如何使用
pip
在特定位置安装软件包。 示例使用
--install option=“--install lib=/path/”
但不支持:

在--install选项:['--install lib']中找到位置更改选项 从命令行。此配置可能会导致意外行为 而且不受支持。PIP20.2将删除对此的支持 功能。一种可能的替代方法是使用pip级别的选项,如 --用户、-prefix、-root和--target。您可以在上找到关于此的讨论

使用
--prefix
会导致类似上面的结构,并出现模块未找到错误

使用
--target
可以找到安装在指定目录中的每个软件包。 在这种情况下,我有一个与熊猫相关的错误

C extension: No module named 'pandas._libs.tslibs.conversion' not built
我猜它与应该在系统级可用的动态库有关

有什么提示吗


谢谢

您所指的气流文档页面说明了打包DAG:

为了实现这一点,您可以创建一个zip文件,该文件在zip文件的根目录中包含DAG,并将额外的模块解压缩到目录中

我对这一点的理解与你的不同。我不认为Airflow将这些打包的DAG作为一个真正的python包来处理。它看起来就像一个自定义的zip文件夹,将添加到您的DAGs文件夹中。因此,您拥有的lib或lib64文件夹可能不是真正的python模块(它们没有
\uuu init\uuu.py
文件)。这就是为什么他们说“额外的模块应该在目录中解包”

看看他们给出的示例zip文件:

my_dag1.py
my_dag2.py
package1/__init__.py
package1/functions.py
package1
有一个
初始化.py
文件。因此,您的
vertica_python
库应该可以直接导入,如下所示:

my_custom_package
vertica_python/
predict_dag.py  
train_dag.py
然而,我认为你不应该这样做。我的印象是,您应该在这里添加的模块是您自己开发的模块,而不是第三方库


因此,我建议您事先安装运行打包DAG所需的库。

您所指的气流文档页面中有关于打包DAG的说明:

为了实现这一点,您可以创建一个zip文件,该文件在zip文件的根目录中包含DAG,并将额外的模块解压缩到目录中

我对这一点的理解与你的不同。我不认为Airflow将这些打包的DAG作为一个真正的python包来处理。它看起来就像一个自定义的zip文件夹,将添加到您的DAGs文件夹中。因此,您拥有的lib或lib64文件夹可能不是真正的python模块(它们没有
\uuu init\uuu.py
文件)。这就是为什么他们说“额外的模块应该在目录中解包”

看看他们给出的示例zip文件:

my_dag1.py
my_dag2.py
package1/__init__.py
package1/functions.py
package1
有一个
初始化.py
文件。因此,您的
vertica_python
库应该可以直接导入,如下所示:

my_custom_package
vertica_python/
predict_dag.py  
train_dag.py
然而,我认为你不应该这样做。我的印象是,您应该在这里添加的模块是您自己开发的模块,而不是第三方库

因此,我建议您事先安装运行打包DAG所需的库。

Ciao Marco

我知道这是一个老生常谈的问题,但我必须经历同样的过程,对我有用的是:

pip install -r ../requirements_dag.txt --target="$PWD"
这同样适用于git上托管的包。关键区别在于使用了
--target
而不是
--prefix

Ciao Marco

我知道这是一个老生常谈的问题,但我必须经历同样的过程,对我有用的是:

pip install -r ../requirements_dag.txt --target="$PWD"

这同样适用于git上托管的包。关键区别在于使用了
--target
而不是
--prefix

在自定义DAGs packages setup.py文件中是否将缺少的
vertica_python
包列为
install_requires
包?还是单独安装?所有软件包(vertica_python、pandas、numpy等)都与我的自定义软件包一起安装在setup.py中。请参阅编辑问题在自定义DAGs packages setup.py文件中,缺少的
vertica\u python
软件包是否列为
install\u requires
软件包?还是单独安装?所有软件包(vertica_python、pandas、numpy等)都与我的自定义软件包一起安装在setup.py中。见编辑问题你好,阿莱西奥,谢谢。但是我认为打包的DAG是一个糟糕的解决方案,因为“打包的DAG不能包含动态库(例如libz.so),如果模块需要这些库,那么这些库需要在系统上可用。换句话说,只有纯python模块可以打包。”我最终使用了bashoperator,代码中有一点开销,但具有语言不可知的优势。我使用打包DAG的主要原因是,我们有来自不同项目/团队的DAG。我们使用KuberneteSecutor以更好的方式处理依赖关系。嗨,alessio,谢谢。