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

Airflow 气流-脚本在初始化期间执行,airflow,airflow-scheduler,Airflow,Airflow Scheduler,我有一个将数据从表2插入表1的脚本。作为airflow初始化过程的一部分,我看到插入函数一直在后台运行,即使我没有触发它或计划它。我想知道是什么错误的脚本,使它自动触发。我需要在下面的脚本中修改什么,以确保它不会在初始化过程中执行该命令 ## Library Imports import psycopg2 import airflow from airflow import DAG from airflow.operators import BashOperator from sqlalchem

我有一个将数据从表2插入表1的脚本。作为airflow初始化过程的一部分,我看到插入函数一直在后台运行,即使我没有触发它或计划它。我想知道是什么错误的脚本,使它自动触发。我需要在下面的脚本中修改什么,以确保它不会在初始化过程中执行该命令

## 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)

如果从Python风格的角度来看DAG,缩进会引起一些思考

首先,尝试仅使用
python名称DAG.py
执行DAG。是,不要使用
气流
命令。气流的某些部分也在执行此操作,以检查要执行的操作

现在,如果正在执行某些代码,则可能会连接到intendation

功能分析

此处的凹痕似乎已破损:

def db_login(): 全球数据库 尝试: db_con=psycopg2.connect(“数据库名='db'用户='user'密码='pass'主机='hostname'端口='5439'sslmode='require') 除: 打印(“我无法连接到数据库。”) 打印('连接任务完成:连接到数据库') 返回(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)
否则,将始终执行最左边的代码

另外:全局变量在气流中的其他方法中不一定可用!要共享连接,请使用气流
XCOM

直接在DAG内调用函数

另外,由于我不知道的原因,您希望执行一些完全不受气流控制的功能,但每次执行时都要执行

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\u callable=load\u etl
(注意:行末没有括号)

谢谢您的反馈。请相信,当我在这里输入值时,Python脚本的对齐错误了。我能够执行脚本的Python部分,它的工作方式与预期的一样好。但是,您能否帮助我如何使这些功能完全不受气流的控制,而是在每次执行时。谢谢……是的,我去了。已将更新的代码粘贴到原始邮件中。仍然有相同的问题,其中脚本在初始化气流时默认运行。@暗马,如果这个答案帮助了你,考虑把它标记为接受,让其他人可以看到。@ toBi6,为混乱道歉。我已经编辑了代码。你能看一下吗。谢谢。我希望你能看到上面更新的代码部分。另外,Python部分的格式是正确的,因为在我结束时运行它时,我能够获得该部分的预期输出。我遇到的问题是,由于我使用的函数预期会将行插入表中,因此当我启动气流(使用“气流initdb”)时,即使我没有触发或计划它运行,查询也会自行开始执行。正在考虑如何确保在没有用户触发的情况下不会在后台运行此功能。。希望这有帮助。Tnx..@tobi6,很抱歉,请您最后看一眼。我相信我在这段时间里没有正确地设置间距。Tnx..@tobi6,感谢您的投入。我不知道我们应该使用PythonOperator以防调用函数。我已经修改了它和函数名。但是,我仍然看到在初始化过程中自动执行插入操作:(请回答您的问题,不要在注释中添加代码。另外,我现在不明白问题所在。您可能需要打开一个新问题。