Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何仅在AWS athena表中使用python中的DAG以Aviable格式创建新分区/数据时触发气流任务?_Python_Airflow_Amazon Athena_Directed Acyclic Graphs_Airflow Scheduler - Fatal编程技术网

如何仅在AWS athena表中使用python中的DAG以Aviable格式创建新分区/数据时触发气流任务?

如何仅在AWS athena表中使用python中的DAG以Aviable格式创建新分区/数据时触发气流任务?,python,airflow,amazon-athena,directed-acyclic-graphs,airflow-scheduler,Python,Airflow,Amazon Athena,Directed Acyclic Graphs,Airflow Scheduler,我有一个场景如下: 仅当源表(Athena)中的任务1和任务2有新数据可用时,才触发任务1和任务2。Task1和Task2的触发器应在一天内出现新数据分区时发生 仅在完成任务1和任务2时触发任务3 仅在任务3完成时触发任务4 我的代码 from airflow import DAG from airflow.contrib.sensors.aws_glue_catalog_partition_sensor import AwsGlueCatalogPartitionSensor from d

我有一个场景如下:

  • 仅当源表(Athena)中的任务1和任务2有新数据可用时,才触发任务1和任务2。Task1和Task2的触发器应在一天内出现新数据分区时发生
  • 仅在完成任务1和任务2时触发任务3
  • 仅在任务3完成时触发任务4
  • 我的代码

    from airflow import DAG
    
    from airflow.contrib.sensors.aws_glue_catalog_partition_sensor import AwsGlueCatalogPartitionSensor
    from datetime import datetime, timedelta
    
    from airflow.operators.postgres_operator import PostgresOperator
    from utils import FAILURE_EMAILS
    
    yesterday = datetime.combine(datetime.today() - timedelta(1), datetime.min.time())
    
    default_args = {
        'owner': 'airflow',
        'depends_on_past': False,
        'start_date': yesterday,
        'email': FAILURE_EMAILS,
        'email_on_failure': False,
        'email_on_retry': False,
        'retries': 1,
        'retry_delay': timedelta(minutes=5)
    }
    
    dag = DAG('Trigger_Job', default_args=default_args, schedule_interval='@daily')
    
    Athena_Trigger_for_Task1 = AwsGlueCatalogPartitionSensor(
        task_id='athena_wait_for_Task1_partition_exists',
        database_name='DB',
        table_name='Table1',
        expression='load_date={{ ds_nodash }}',
        timeout=60,
        dag=dag)
    
    Athena_Trigger_for_Task2 = AwsGlueCatalogPartitionSensor(
        task_id='athena_wait_for_Task2_partition_exists',
        database_name='DB',
        table_name='Table2',
        expression='load_date={{ ds_nodash }}',
        timeout=60,
        dag=dag)
    
    execute_Task1 = PostgresOperator(
        task_id='Task1',
        postgres_conn_id='REDSHIFT_CONN',
        sql="/sql/flow/Task1.sql",
        params={'limit': '50'},
        trigger_rule='all_success',
        dag=dag
    )
    
    execute_Task2 = PostgresOperator(
        task_id='Task2',
        postgres_conn_id='REDSHIFT_CONN',
        sql="/sql/flow/Task2.sql",
        params={'limit': '50'},
        trigger_rule='all_success',
        dag=dag
    )
    
    
    
    execute_Task3 = PostgresOperator(
        task_id='Task3',
        postgres_conn_id='REDSHIFT_CONN',
        sql="/sql/flow/Task3.sql",
        params={'limit': '50'},
        trigger_rule='all_success',
        dag=dag
    )
    
    execute_Task4 = PostgresOperator(
        task_id='Task4',
        postgres_conn_id='REDSHIFT_CONN',
        sql="/sql/flow/Task4",
        params={'limit': '50'},
        dag=dag
    )
    
    
    
    execute_Task1.set_upstream(Athena_Trigger_for_Task1)
    execute_Task2.set_upstream(Athena_Trigger_for_Task2)
    
    execute_Task3.set_upstream(execute_Task1)
    execute_Task3.set_upstream(execute_Task2)
    
    execute_Task4.set_upstream(execute_Task3)
    

    实现这一目标的最佳方式是什么?

    我相信你的问题解决了两个主要问题:

  • 忘记以明确的方式配置
    计划间隔
    ,因此@daily设置了一些您不期望的内容
  • 当您依赖外部事件来完成dag的执行时,如何正确地触发和重试dag的执行
  • 简短的回答是:使用cron作业格式明确设置您的计划时间间隔,并使用传感器操作员不时进行检查

    from airflow import DAG
    
    from airflow.contrib.sensors.aws_glue_catalog_partition_sensor import AwsGlueCatalogPartitionSensor
    from datetime import datetime, timedelta
    
    from airflow.operators.postgres_operator import PostgresOperator
    from utils import FAILURE_EMAILS
    
    yesterday = datetime.combine(datetime.today() - timedelta(1), datetime.min.time())
    
    default_args = {
        'owner': 'airflow',
        'depends_on_past': False,
        'start_date': yesterday,
        'email': FAILURE_EMAILS,
        'email_on_failure': False,
        'email_on_retry': False,
        'retries': 1,
        'retry_delay': timedelta(minutes=5)
    }
    
    dag = DAG('Trigger_Job', default_args=default_args, schedule_interval='@daily')
    
    Athena_Trigger_for_Task1 = AwsGlueCatalogPartitionSensor(
        task_id='athena_wait_for_Task1_partition_exists',
        database_name='DB',
        table_name='Table1',
        expression='load_date={{ ds_nodash }}',
        timeout=60,
        dag=dag)
    
    Athena_Trigger_for_Task2 = AwsGlueCatalogPartitionSensor(
        task_id='athena_wait_for_Task2_partition_exists',
        database_name='DB',
        table_name='Table2',
        expression='load_date={{ ds_nodash }}',
        timeout=60,
        dag=dag)
    
    execute_Task1 = PostgresOperator(
        task_id='Task1',
        postgres_conn_id='REDSHIFT_CONN',
        sql="/sql/flow/Task1.sql",
        params={'limit': '50'},
        trigger_rule='all_success',
        dag=dag
    )
    
    execute_Task2 = PostgresOperator(
        task_id='Task2',
        postgres_conn_id='REDSHIFT_CONN',
        sql="/sql/flow/Task2.sql",
        params={'limit': '50'},
        trigger_rule='all_success',
        dag=dag
    )
    
    
    
    execute_Task3 = PostgresOperator(
        task_id='Task3',
        postgres_conn_id='REDSHIFT_CONN',
        sql="/sql/flow/Task3.sql",
        params={'limit': '50'},
        trigger_rule='all_success',
        dag=dag
    )
    
    execute_Task4 = PostgresOperator(
        task_id='Task4',
        postgres_conn_id='REDSHIFT_CONN',
        sql="/sql/flow/Task4",
        params={'limit': '50'},
        dag=dag
    )
    
    
    
    execute_Task1.set_upstream(Athena_Trigger_for_Task1)
    execute_Task2.set_upstream(Athena_Trigger_for_Task2)
    
    execute_Task3.set_upstream(execute_Task1)
    execute_Task3.set_upstream(execute_Task2)
    
    execute_Task4.set_upstream(execute_Task3)
    
    从中,您可以看到您实际上正在做:
    @每日-每天午夜运行一次

    这就解释了为什么出现超时错误,并在5分钟后失败,因为您设置了
    'retries':1
    'retry\u delay':timedelta(分钟=5)
    。所以它尝试在午夜运行dag,但失败了。5分钟后重试,再次失败,因此它将标记为失败

    因此,基本上@daily run将隐式cron作业设置为:

    @daily -> Run once a day at midnight -> 0 0 * * *
    
    cron作业格式如下所示,只要您想说“全部”,就可以将该值设置为
    *

    一周中的分时日

    所以@daily基本上是说每分钟运行一次:每分钟0小时0天/月/月/月/月/天/周

    因此,您的案例每分钟运行一次:0小时10天10个月10个月10个月10个月10个月。这将以cron作业格式转换为:

    0 10 * * *
    
    当您依赖外部事件来完成dag执行时,如何正确触发和重试dag执行

  • 您可以使用命令
    气流触发器\u dag
    从外部事件触发气流中的dag。如果您知道如何触发lambda函数/python脚本来针对您的实例,这将是可能的

  • 如果无法从外部触发dag,则使用类似OP的传感器操作器,为其设置一个触发时间,并设置合理的高重试次数


  • 您对此解决方案有什么问题吗?@Bernardostarnsreesen,有时
    Task1
    Task2
    会循环运行。对我来说,数据被加载到欧洲中部时间上午10点的雅典娜数据源表中。你的意思是说,气流多次重试Task1和Task2,直到成功吗?@Bernardostarnsreesen,是的exactly@Bernardostearnsreisen,我不知道如何奖励赏金:)谢谢你。另外,如果我想根据事件而不是时间触发任务,即只要源“AWS Athena Tables”中有新的数据分区,就应该触发下一个任务。那我怎么安排呢。我当前的代码是否足够合适。@pankaj,我只看到两种选择。我对aws athena了解不多,但您可以使用命令
    aiffair trigger\u dag
    从外部事件触发气流中的dag。如果您能够触发lambda函数/python脚本来针对您的airflow实例,那么这是可能的。另一种选择是或多或少地执行您正在执行的操作,因为您没有基于事件的触发器,您需要定期检查此事件是否发生。因此,使用此当前解决方案将设置一个cron作业,时间范围为小时,以分钟的高频率运行dag。。。许多人会失败,但它将能够相当快地赶上事件后happens@Bernado,我在气流中找到了名为
    AwsGlueCatalogPartitionSensor
    的包,以及用于分区出口的气流命令
    {{ds_nodash}
    。那么我的问题是如何安排这项工作。@Benado,你能看看我的代码在哪里实现了上述检查并给出你的输入吗
    0 10 * * *