繁体   English   中英

如何自动化整个 Python 脚本以通过 Airflow 运行?

[英]How to automate a whole Python script to run via Airflow?

我有一个 Python 脚本,它指向一个 elasticsearch 集群,对数据执行聚合和计算,然后将见解存储在本地 PostgreSQL 中。 该脚本可以根据用户偏好每天或每周运行,如下所示:

python script.py --approach daily 
python script.py --approach weekly

我想通过 Airflow 自动运行此数据流工作流程,每 10 分钟运行一次。

My guess is to go for the bashoperator as to create a task t1 = bashoperator that executes the bash command python script.py --approach daily as a DAG1, and t2 = bashoperator that executes the bash command python script.py --approach weekly

该代码似乎没有给出适当的结果,因为 Airflow 的 webUI 似乎将所有作业都安排到了计划中。

谁能告诉我我做错了什么?


#imports 
    from airflow.models import DAG
    from airflow.operators.bash_operator import BashOperator
    from  airflow.operators.python_operator import PythonOperator
    from  airflow.operators.email_operator import EmailOperator

    from datetime import datetime, timedelta

    seven_days_ago = datetime.combine(datetime.today() - timedelta(7),
                                        datetime.min.time())

    default_args = {
        
        'owner': 'me',
        'depends_on_past': False,
        'start_date': seven_days_ago,
        'email': ['me@gmail.com'],
        'email_on_failure': True,
        'email_on_retry': False
        'retries': 3,
        'max_tries' : 3 , 
        'retry_delay': timedelta(minutes=10) 

        }

    etl_dag = DAG('tester',default_args=default_args,schedule_interval= '@once')

    #the bashoperator to execute the bash command as to automate the task execution every 5 min 
    weekly_task = BashOperator(
    task_id='testing',
    bash_command='python  my_script.py --approach weekly',
    dag=etl_dag)

您在这里有几种方法:

  1. 写两个 DAG。 每天一份,每周一份。
  2. 使用DayOfWeekBranchOpeator编写一个 DAG,该 DAG 将根据特定日期分支您的工作流。 例如:在星期一,它将--approach weekly ,而在所有其他日子,它将每天执行--approach

如果您正在运行Airflow>= 2.1.0 (尚未发布):

from airflow.operators.weekday import BranchDayOfWeekOperator
from airflow.operators.bash import BashOperator

with DAG(
    dag_id='tester',
    default_args=default_args,
    schedule_interval='@daily'
) as dag:

    branch_op = BranchDayOfWeekOperator(
        task_id="branch_task",
        follow_task_ids_if_true="weekly_task",
        follow_task_ids_if_false="daily_task",
        week_day="MONDAY", # Replace with the day you want to execute the approch weekly
        use_task_execution_day=False, # Set true if you want the day to be checked against execution_date
    )
    weekly_op = BashOperator(
        task_id='weekly_task',
        bash_command='python  my_script.py --approach weekly',
    )
    daily_op = BashOperator(
        task_id='daily_task',
        bash_command='python  my_script.py --approach daily',
    )

    branch_op >> [weekly_op, daily_op]

如果您正在运行Airflow< 2.1.0

DayOfWeekBranchOpeator代码复制到您的项目中,将其导入本地并使用与上述相同的代码。 DayOfWeekBranchOpeator是 Airflow 2.1 版本中的新功能。 请注意,您可能需要更改运算符中的一些导入,这取决于您正在运行的 Airflow 版本。

根据您的语法,我假设您正在运行 Airflow 1.10.14。

我认为您正在尝试完成以下任务:

  • 每天运行 my_script.py
  • 每周运行 my_script.py

您将需要更改您的脚本以执行一个工作流程周期。 这是因为 Airflow 将在每个计划间隔执行您的脚本。 如果您的脚本已运行并且具有内部调度过程(假设这是--approach确定的内容),它将与 Airflow 的核心目的相冲突,即管理您的工作流程。 每次 Airflow 运行脚本时,它都会启动另一个每周运行的进程(对于--approach weekly ),从而使工作流程相乘。

您希望 Airflow 安排您的工作流程,而不是脚本。


具有单独 schedule_interval 的两个 DAG 将在这里工作。

daily_dag.py

from airflow.models import DAG
from airflow.operators.bash_operator import BashOperator

from datetime import datetime

dag = DAG(
    dag_id='daily_dag',
    start_date=datetime(2021, 1, 1),
    schedule_interval='0 7 * * *'
)
with dag:
    run_script = BashOperator(
        task_id='run_script',
        bash_command='python my_script.py',
    )

该 DAG 将在每天 7 点 UTC 运行工作流。

每周运行.py

from airflow.models import DAG
from airflow.operators.bash_operator import BashOperator

from datetime import datetime

dag = DAG(
    dag_id='weekly_dag',
    start_date=datetime(2021, 1, 1),
    schedule_interval='0 7 * * Mon'
)
with dag:
    run_script = BashOperator(
        task_id='run_script',
        bash_command='python my_script.py',
    )

此 DAG 将在每周一 7 UTC 运行工作流。

将它们分开可以让您拥有更清晰的管道以及更清晰地定义每个管道在自己的频率下所做的事情。

我还将考虑通过直接执行 python 代码而不是通过 shell 将这些 BashOperator 转换为PythonOperators以删除抽象层。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM