Airflow Google数据流:导入自定义Python模块

Airflow Google数据流:导入自定义Python模块,airflow,google-cloud-dataflow,apache-beam,google-cloud-composer,Airflow,Google Cloud Dataflow,Apache Beam,Google Cloud Composer,我尝试在Google Cloud数据流中运行Apache Beam管道(Python),由Google Cloud Coomposer中的DAG触发 各GCS存储桶中我的dags文件夹的结构如下所示: /dags/ dataflow.py <- DAG dataflow/ pipeline.py <- pipeline setup.py my_modules/ __init__.py commons.py <- the m

我尝试在Google Cloud数据流中运行Apache Beam管道(Python),由Google Cloud Coomposer中的DAG触发

各GCS存储桶中我的dags文件夹的结构如下所示:

/dags/
  dataflow.py <- DAG
  dataflow/
    pipeline.py <- pipeline
    setup.py
    my_modules/
      __init__.py
      commons.py <- the module I want to import in the pipeline
在DAG文件(dataflow.py)中,我设置
setup\u file
选项并将其传递给dataflow:

default_dag_args = {
    ... ,
    'dataflow_default_options': {
        ... ,
        'runner': 'DataflowRunner',
        'setup_file': os.path.join(configuration.get('core', 'dags_folder'), 'dataflow', 'setup.py')
    }
}
在管道文件(pipeline.py)中,我尝试使用

from my_modules import commons
但这失败了。Google Cloud Composer(Apache Airflow)中的日志显示:

setup.py文件背后的基本思想已记录在案

此外,关于SO的一些类似问题也帮助了我:


实际上,我想知道为什么我的管道会出现
语法错误,而不是
模块未找到
之类的错误…

我试图重现您的问题,然后尝试解决它,所以我创建了与您相同的文件夹结构:

/dags/
  dataflow.py
  dataflow/
     pipeline.py -> pipeline
     setup.py
     my_modules/
        __init__.py
        common.py
因此,为了使其正常工作,我所做的更改是将这些文件夹复制到实例正在运行的位置,以便代码能够找到它,例如在实例的
/tmp/
文件夹中

所以,我的DAG应该是这样的:

1-首先,我声明我的论点:

default_args = {
   'start_date': datetime(xxxx, x, x),
   'retries': 1,
   'retry_delay': timedelta(minutes=5),
   'dataflow_default_options': {
       'project': '<project>',
       'region': '<region>',
       'stagingLocation': 'gs://<bucket>/stage',
       'tempLocation': 'gs://<bucket>/temp',
       'setup_file': <setup.py>,
       'runner': 'DataflowRunner'
   }
} 
我就是这样创建了DAG文件
dataflow.py
,然后在
pipeline.py
中,要导入的包如下所示:

from my_modules import commons

它应该可以正常工作,因为VM可以理解文件夹目录。

它看起来像是语法问题。既然是python,您是否正确检查了空格?
default_args = {
   'start_date': datetime(xxxx, x, x),
   'retries': 1,
   'retry_delay': timedelta(minutes=5),
   'dataflow_default_options': {
       'project': '<project>',
       'region': '<region>',
       'stagingLocation': 'gs://<bucket>/stage',
       'tempLocation': 'gs://<bucket>/temp',
       'setup_file': <setup.py>,
       'runner': 'DataflowRunner'
   }
} 
with DAG(
    'composer_df',
     default_args=default_args,
     description='datflow dag',
     schedule_interval="xxxx") as dag:

     def copy_dependencies():
          process = subprocess.Popen(['gsutil','cp', '-r' ,'gs://<bucket>/dags/*', 
          '/tmp/'])
          process.communicate()


     t1 = python_operator.PythonOperator(
        task_id='copy_dependencies',
        python_callable=copy_dependencies,
        provide_context=False
     )


     t2 = DataFlowPythonOperator(task_id="composer_dataflow", 
          py_file='/tmp/dataflow/pipeline.py', job_name='job_composer')

     t1 >> t2
from my_modules import commons