气流无法使用GoogleCloud Operatos遍历xcom_pull列表

时间:2019-07-04 13:12:24

标签: airflow

我想动态获取gcs存储桶中的csv文件列表,然后将每个文件转储到相应的BQ表中。

我正在使用 GoogleCloudStorageListOperator GoogleCloudStorageToBigQueryOperator 运算符

GCS_Files = GoogleCloudStorageListOperator(
                task_id='GCS_Files',
                bucket=cf.storage.import_bucket_name,
                prefix='20190701/',
                delimiter='.csv',
                dag=dag
            )

for idx, elem in enumerate(["{{ task_instance.xcom_pull(task_ids='GCS_Files') }}"]):
    storage_to_bigquery = GoogleCloudStorageToBigQueryOperator(
            task_id='storage_to_bigquery',
            bucket=cf.storage.import_bucket_name,
            create_disposition='CREATE_IF_NEEDED',
            autodetect=True,
            destination_project_dataset_table=f"{cf.project}.{cf.bigquery.core_dataset_name}.{idx}",
            skip_leading_rows=1,
            source_format='CSV', 
            source_objects=[f'{elem}'],
            write_disposition='WRITE_TRUNCATE',
            dag=dag
            )

    storage_to_bigquery.set_upstream(GCS_Files)

但是,该列表一次无法迭代一次,并抛出以下错误。

googleapiclient.errors.HttpError: <HttpError 400 when requesting https://bigquery.googleapis.com/bigquery/v2/projects/my-project/jobs?alt=json returned "Source URI must not contain the ',' character: gs://mybucket/['20190701/file0.csv', '20190701/file1.csv', '20190701/file2.csv']">

有什么建议吗?预先感谢。

1 个答案:

答案 0 :(得分:1)

您不能从代码的任何地方调用宏。 这在您的代码中被视为字符串:“ {{task_instance.xcom_pull(task_ids ='GCS_Files')}}” 后来由Jinja2在传递给gcp运算符时进行了评估,因为您使用的是模板字段:https://github.com/apache/airflow/blob/21a7e7ec67ac7a391d837aa7c13c0825683f1349/airflow/contrib/operators/gcs_to_bq.py#L140

要能够调用task_instance.xcom_pull,您需要具有一个上下文,该上下文只能在DAG运行中存在。当Airflow懒惰地评估DAG时,此功能不可用。

对于您而言,最好的方法是使用SubDAG来循环操作员,并使用您的宏来生成要循环处理的文件列表:https://airflow.apache.org/concepts.html#subdags