调用函数后,GCP Composer / Airflow无法识别DAG

时间:2019-06-05 15:53:26

标签: python airflow google-cloud-composer

我有一个从BigQuery数据集中获取表列表的函数:

def get_table_names(**kwargs):

    client = bigquery.Client()

    # get source tables

    source_tables = []

    for table in client.list_tables(
            Template('$project.$dataset').substitute(project=SOURCE_PROJECT, dataset=SOURCE_DATASET)):

        if table.table_id.startswith(TABLE_PREFIX):
            source_tables.append(table.table_id)

    logging.info(str(len(source_tables)) + ' tables scheduled to move')

    return source_tables

我最初是在PythonOperator类型的任务中调用此函数的,尽管我没有返回任何值,但它运行良好,并注销了“计划移动的524个表”。

我现在将其称为dag设置的一部分,以便可以实例化每个表的任务(我尚未编写此部分):

table_tasks = get_table_names()

但是,一旦我调用它,Composer / Airflow Web界面就会停止识别DAG-它仍然被列出,并且如果我单击重新加载图标,我会得到通常的“新鲜的雏菊消息”,但是如果我尝试去进入DAG我得到:

  

DAG“ GA360_Replication”似乎丢失了

1 个答案:

答案 0 :(得分:0)

缺少DAG的最可能原因是代码中的错误,使调度程序无法接收DAG。您也可以检查是否有2个具有相同DAG名称的.py文件。当您替换上载具有不同名称但DAG名称相同的.py文件(即使您删除了先前的.py文件)时,我也看到了这种情况。不检查环境/日志很难排除故障,但是我认为这是最可能的情况。如果您仍然遇到此问题,请随时contact support

无论哪种方式,我都使此DAG在Composer 1.7.1 Airflow 1.10.2和Python3中都能正常工作。阅读问题和代码,感觉到您要将列表传递到表中的下一个任务,因此我添加了一个简单地使用XCOM打印它们的表:

import datetime
import os
import airflow
from airflow import models
from airflow.operators import python_operator
from google.cloud import bigquery
import time
import logging

default_dag_args = { 'owner': 'airflow', 'start_date': airflow.utils.dates.days_ago(1) }

with models.DAG( 'test_table_xcom', default_args=default_dag_args, schedule_interval = "@daily") as dag:

TABLE_PREFIX = 'test' SOURCE_PROJECT = <PROJECT> SOURCE_DATASET = <DATASET> def get_table_names(**kwargs): client = bigquery.Client() source_tables = [] dataset = '{}.{}'.format(SOURCE_PROJECT,SOURCE_DATASET) for table in client.list_tables(dataset): if table.table_id.startswith(TABLE_PREFIX): source_tables.append(table.table_id) logging.info('{} tables scheduled to move'.format(len(source_tables))) return source_tables def print_tables(**kwargs): ti = kwargs['ti'] tables_list = ti.xcom_pull(task_ids='list_tables') for table in tables_list: print(table) listTables = python_operator.PythonOperator(task_id='list_tables',python_callable=get_table_names, provide_context=True) tablePrint = python_operator.PythonOperator(task_id='print_tables',python_callable=print_tables, provide_context=True) listTables >> tablePrint

最后但并非最不重要的一点,请注意,Airflow本身并不是进行ETL操作而是对其进行调度的 meant 。不建议使用XCOM(如*所示),因为它可能会使在Airflow / Composer的幕后运行的数据库(在这种情况下为Cloud SQL)过载。对于您要传输表名列表的特定情况,我认为这不会有问题,但是最好知道此建议。

  

*如果两个运算符需要共享信息,例如文件名或少量数据,则应考虑将它们合并为一个运算符。