【问题标题】:Customizing Airflow BashOperator自定义气流 BashOperator
【发布时间】:2020-03-16 09:16:07
【问题描述】:

我正在尝试自定义 Airflow BashOperator,但它不起作用。到目前为止,我已经尝试过这个

my_operators.py

from airflow.utils.decorators import apply_defaults
from airflow.operators.bash_operator import BashOperator

class MyCopyOperator(BashOperator):

    template_fields = ('bash_command', 'source_file', 'source_dir', 'target_file', 'target_dir')


    @apply_defaults
    def __init__(
            self,
            bash_command,
            source_file, 
            source_dir, 
            target_file, 
            target_dir,
            *args, **kwargs):

        super(MyCopyOperator, self).__init__(*args, **kwargs)
        self.bash_command = bash_command
        self.source_file = source_file
        self.source_dir = source_dir
        self.target_file = target_file
        self.target_dir = target_dir     

    def execute(self, context):


        self.bash_command =  "cp " + " " + self.source_dir + "/" + self.source_file + " " + self.target_dir + "/" + self.target_file
        super().bash_command =  self.bash_command
        print(super.bash_command)
        print(F"inherited {self.bash_command}")
        super().execute(self,context)

operator_example.py

from datetime import datetime, timedelta
from airflow import DAG
from airflow.models import Variable
from airflow.exceptions import AirflowException
from my_operators import MyCopyOperator

dag_name= 'my_test_dag'

owner = Variable.get("owner_" + dag_name)


default_args = {
    "owner": owner,
    "depends_on_past": False,
    "start_date": datetime(2019, 10, 31),
    'email': ['airflow@example.com'],
    "email_on_failure": False,
    "email_on_retry": False,
    "retries": 1,
    "retry_delay": timedelta(minutes=5),
}

dag = DAG(dag_id=dag_name, default_args=default_args, schedule_interval=None)


copytest_task=MyCopyOperator(
     task_id='copytest_task',
     bash_command="cp",
     source_file="test_file.txt",
     source_dir='/usr/local/airflow',
     target_file="test_file.copied.txt",
     target_dir='/usr/local/airflow',
     dag=dag,
     provide_context=True,
)


copytest_task

Airflow GUI 显示错误消息 Broken DAG: [/usr/local/airflow/dags/operator_example.py] Argument ['bash_command'] is required

这次尝试有什么问题?我知道我可以从 https://github.com/apache/airflow/blob/master/airflow/operators/bash_operator.py 复制或模仿 BashOperator 的实现,但这不是我想要的。

【问题讨论】:

    标签: python airflow


    【解决方案1】:

    使用以下运算符。注意我们如何将bash_command 传递给我们继承自的类。

    from airflow.utils.decorators import apply_defaults
    from airflow.operators.bash_operator import BashOperator
    
    class MyCopyOperator(BashOperator):
    
        template_fields = ('bash_command', 'source_file', 'source_dir', 'target_file', 'target_dir')
    
    
        @apply_defaults
        def __init__(
                self,
                source_file, 
                source_dir, 
                target_file, 
                target_dir,
                *args, **kwargs):
    
            super(MyCopyOperator, self).__init__(bash_command="cp " + " " + source_dir + "/" + source_file + " " + target_dir + "/" + target_file, *args, **kwargs)
            self.source_file = source_file
            self.source_dir = source_dir
            self.target_file = target_file
            self.target_dir = target_dir     
    
    

    示例任务:

    MyCopyOperator(
        task_id='print_date12',
        source_file='test.txt',
        source_dir='/Users/kaxilnaik/Desktop',
        target_file="test1.txt",
        target_dir="/Users/kaxilnaik/Desktop/abc",
        dag=dag)
    

    【讨论】:

    • 非常感谢,它可以工作,但是在运行 DAG 时,我收到错误消息 cp: missing file operand 而具有相同 bash_command 的 BashOperator 就像一个魅力 @987654325 @
    • 我已经更新了答案,请使用它并检查。我还添加了一个对我有用的示例任务。
    • 现在可以了。非常感谢。我使用 MyCopyOperator( task_id='print_date12', bash_command="############", source_file='test.txt', source_dir='/usr/local/airflow', target_file ="test1.txt", target_dir="/usr/local/airflow", dag=dag)
    • Np :)。我再次编辑了答案。使用新代码,您无需输入bash_command="############" :)
    • 如果任何参数包含引号字符、通配符、空格等,这将以令人讨厌的方式失败。一个更好但更复杂的解决方案将避免完全为这个简单的操作调用 shell,只需使用subprocess.run() 直接致电cp。也许也可以看看stackoverflow.com/questions/4256107/…
    猜你喜欢
    • 2022-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 2021-04-23
    • 1970-01-01
    • 2022-09-23
    相关资源
    最近更新 更多