气流 - 脚本在初始化期间执行

时间:2018-05-25 05:57:05

标签: airflow airflow-scheduler

我有一个Airflow脚本,可以将table_2中的数据插入到table_1中。作为气流初始化过程的一部分,我看到即使我没有触发或计划,插入功能仍在后台运行。我想知道脚本中有什么错误使它自动触发。我需要在下面的脚本中修改什么,以确保它不会在初始化过程中执行命令。

## Library Imports
import psycopg2
import airflow
from airflow import DAG
from airflow.operators import BashOperator
from sqlalchemy import create_engine
import io


# Following are defaults which can be overridden later on
default_args = {
'owner': 'admin',
'depends_on_past': False,
'start_date': datetime(2018, 5, 25),
'email': ['admin@mail.com'],
'email_on_failure': True,
'email_on_retry': True,
'retries': 1,
'retry_delay': timedelta(minutes=1),
}

dag = DAG('sample', default_args=default_args)


#######################

def db_login():
    global db_con
try:
    db_con = psycopg2.connect(" dbname = 'db' user = 'user' password = 'pass' host = 'hostname' port = '5439' sslmode = 'require' ")
except:
    print("I am unable to connect to the database.")
print('Connection Task Complete: Connected to DB')
return(db_con)


#######################

def insert_data():
    cur = db_con.cursor()
    cur.execute("""insert into table_1 select id,name,status from table_2 limit 2 ;""")
    db_con.commit()
    print('ETL Task Complete: Inserting data into table_1')


db_login()
insert_data()
db_con.close()

##########################################


t1 = BashOperator(
task_id='db_con',
python_callable=db_login(),
bash_command='python3 ~/airflow/dags/sample.py',
email_on_failure=True,
email=['admin@mail.com'],
dag=dag)

t2 = BashOperator(
task_id='insert',
python_callable=insert_data(),
bash_command='python3 ~/airflow/dags/sample.py',
email_on_failure=True,
email=['admin@mail.com'],
dag=dag)


t1.set_downstream(t2)

任何人都可以为此提供帮助。感谢。

更新代码:

## Third party Library Imports

import psycopg2
import airflow
from airflow import DAG
from airflow.operators import BashOperator
from datetime import datetime, timedelta
from sqlalchemy import create_engine
import io



default_args = {
'owner': 'admin',
#'depends_on_past': False,
'start_date': datetime(2018, 5, 25),
 'email': ['admin@mail.com'],
 'email_on_failure': True,
 'email_on_retry': True,
 'retries': 1,
 'retry_delay': timedelta(minutes=1), }

dag = DAG('sample', default_args=default_args, catchup=False, schedule_interval="@once")


def db_login():
    global db_con
    try:
        db_con = psycopg2.connect(
        " dbname = 'db' user = 'user' password = 'password' host = 'host' port = '5439' sslmode = 'require' ")
    except:
        print("I am unable to connect to the database.")
    print('Connection success')
    return (db_con)

def insert_data():
    cur = db_con.cursor()
    cur.execute("""insert into table_1 select id,name,status from table_2 limit 2;""")
    db_con.commit()
    print('ETL Task Complete: Inserting data into table_1')

def load_etl():
    db_login()
    insert_data()
    dwh_connection.close()

#Function to execute the query
load_etl()

t1 = BashOperator(
    task_id='db_connection',
    python_callable=load_etl(),
    bash_command='python3 ~/airflow/dags/sample.py',
    email_on_failure=True,
    email=['admin@mail.com'],
    dag=dag)

#t2 = BashOperator(
#task_id='ops_load_del',
#python_callable=insert_data(),
#bash_command='python3 ~/airflow/dags/sample.py',
#email_on_failure=True,
#email=['admin@mail.com'],
#dag=dag)

t1
#t1.set_downstream(t2)

1 个答案:

答案 0 :(得分:1)

如果从Python式的角度来看你的DAG,那么缩进就会激起一些想法。

首先,尝试使用python name-of-dag.py执行DAG。是的,不要使用airflow命令。 Airflow的某些部分也在进行此操作,以检查要做什么。

现在,如果正在执行某些代码,则可能会将其连接到该意图。

功能分析

这里的缩进似乎破了:

def db_login():     全局db_con 尝试:     db_con = psycopg2.connect(" dbname =' db' user =' user' password =' pass' host =' hostname' port =' 5439' sslmode ='要求'") 除了:     打印("我无法连接到数据库。") 打印('连接任务完成:连接到DB') 返回(db_con)

应该是:

def db_login():
    global db_con
    try:
        db_con = psycopg2.connect(" dbname = 'db' user = 'user' password = 'pass' host = 'hostname' port = '5439' sslmode = 'require' ")
    except:
        print("I am unable to connect to the database.")
    print('Connection Task Complete: Connected to DB')
    return(db_con)

否则将始终执行最左侧的代码。

另外:全局变量不会在Airflow的其他方法中可用!要共享连接,请使用例如气流XCOMhttps://airflow.apache.org/concepts.html#xcoms

直接在DAG中调用函数

另外,由于某些原因我不知道,你想要完全在Airflow 的控制范围之外执行某些函数,但每次执行时都要执行。

db_login() 
insert_data()
db_con.close()

此代码将在每次调用DAG时执行 (可能很多),并且可能与您想要的日程安排完全不同。

如果您希望此代码用于测试目的,您可能希望将其置于主调用中:

if __name__ == '__main__':
    db_login() 
    insert_data()
    db_con.close()

即使您这样做 - 关闭操作仅在此工作流程中可用,但在DAG中不可用。没有任务可以关闭连接。

由于您正在使用PythonOperator,因此构建一个小的def来执行此操作并且只有一个调用此def的任务也是明智的:

def load_etl():
    db_login() 
    insert_data()
    db_con.close()

<强> TL / DR 消除所有缩进错误,这样如果您纯粹使用Python调用该文件,则不会执行任何代码。

修改

这也意味着任何函数调用都不在任务或def之外。这一行

#Function to execute the query
load_etl()

将被执行,因为它不是任务或def的一部分。它必须被删除。然后它应该工作,因为函数调用是任务的一部分。

由于此函数是Python函数,因此您应该使用PythonOperator及其参数python_callable=load_etl(注意:行尾没有括号)