我尝试由Google Cloud Coomposer中的DAG触发,在Google Cloud Dataflow中运行Apache Beam管道(Python)。
我的dags文件夹在相应的GCS存储桶中的结构如下:
/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
setup.py是非常基本的,但是根据Apache Beam的文档和答案:
import setuptools
setuptools.setup(setuptools.find_packages())
在DAG文件(dataflow.py)中,设置setup_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)中的日志显示:
gcp_dataflow_hook.py:132} WARNING - b' File "/home/airflow/gcs/dags/dataflow/dataflow.py", line 11\n from my_modules import commons\n ^\nSyntaxError: invalid syntax'
setup.py文件背后的基本思想记录在here
中另外,关于SO的类似问题也对我有帮助:
Google Dataflow - Failed to import custom python modules
Dataflow/apache beam: manage custom module dependencies
我实际上是在想为什么我的管道失败并出现Syntax Error
而不是module not found
的错误...
答案 0 :(得分:1)
我试图重现您的问题,然后尝试解决它,所以我创建了与您已经拥有的文件夹结构相同的文件
/dags/
dataflow.py
dataflow/
pipeline.py -> pipeline
setup.py
my_modules/
__init__.py
common.py
因此,要使其正常工作,我所做的更改是将这些文件夹复制到实例正在运行的位置,例如,在实例的/tmp/
文件夹中,代码可以找到它。 / p>
所以,我的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'
}
}
2-之后,我创建了DAG,然后在运行数据流任务之前,将上面创建的整个文件夹目录复制到实例/tmp/
的{{1}}文件夹中,然后,我从/ tmp /目录Task t1
运行管道:
Task t2
这就是我创建DAG文件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
的方式,然后在dataflow.py
中导入的包如下:
pipeline.py
应该正常工作,因为VM可以理解文件夹目录。