Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/310.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
Python 基于文件系统更改触发dag_Python_Airflow_Directed Acyclic Graphs - Fatal编程技术网

Python 基于文件系统更改触发dag

Python 基于文件系统更改触发dag,python,airflow,directed-acyclic-graphs,Python,Airflow,Directed Acyclic Graphs,我正在尝试编写一个管道,当postgres db被带到文件夹时,它应该用csv的内容进行更新。我已经编写了一个dag,它创建表格,并在从web UI触发csv内容时推送该内容。代码如下: from datetime import datetime from airflow import DAG from airflow.utils.trigger_rule import TriggerRule from airflow.operators.postgres_operator import Pos

我正在尝试编写一个管道,当postgres db被带到文件夹时,它应该用csv的内容进行更新。我已经编写了一个dag,它创建表格,并在从web UI触发csv内容时推送该内容。代码如下:

from datetime import datetime
from airflow import DAG
from airflow.utils.trigger_rule import TriggerRule
from airflow.operators.postgres_operator import PostgresOperator
from airflow.operators.python_operator import PythonOperator
import psycopg2

with DAG('Write_data_to_PG', description='This DAG is for writing data to postgres.', 
    schedule_interval='*/5 * * * *',
         start_date=datetime(2018, 11, 1), catchup=False) as dag:
    create_table = PostgresOperator(
        task_id='create_table',
        sql="""CREATE TABLE users(
            id integer PRIMARY KEY,
            email text,
            name text,
            address text
        )
        """,
    )

    def my_func():
        print('Pushing data in database.')
        conn = psycopg2.connect("host=localhost dbname=testdb user=testuser")
        print(conn)

        cur = conn.cursor()
        print(cur)

        with open('test.csv', 'r') as f:
            next(f)  # Skip the header row.
            cur.copy_from(f, 'users', sep=',')

        conn.commit()
        print(conn)
        print('DONE!!!!!!!!!!!.')


    python_task = PythonOperator(task_id='python_task', python_callable=my_func)

    create_table >> python_task
当csv被手动粘贴/带到文件夹中时,我无法确定如何触发任务。
任何帮助都将不胜感激,提前感谢。

听起来您正在寻找文件系统写入事件

有关较低级别的Linux,请查看inotify:

对于同样适用于Mac或windows的更高级别的实现:


其想法是添加事件观察程序/事件处理程序,以在文件/目录修改时进行检测。该事件将包含新创建/修改文件的文件路径。

事实证明,Airflow有一个专门用于此要求的模块。我使用气流本身提供的文件传感器解决了这个问题

根据doucmentation:

FileSensor等待文件或文件夹进入文件系统。 如果给定的路径是目录,则此传感器仅在以下情况下返回true 其中存在任何文件(直接或子目录中)

这是修改后的代码,它等待名为test.csv的文件,仅当它在airflow文件夹(或任何文件夹,您需要指定路径)中找到该文件时,才会进入下一个任务:


您可以创建一个DAG,定期检查是否有任何新文件移动到该文件夹,然后如果有任何文件被移动,则从该文件夹触发另一个DAG。谢谢您的回答!Watchdog帮助我监听文件更改,但当文件系统为该文件返回true时,我无法找出如何触发dag。我最终用airflow提供的文件传感器解决了这个问题。@YudhishthirSingh很高兴听到这个消息,我没有意识到这个文件传感器,所以直到有了新的东西;)
from datetime import datetime
from airflow import DAG
from airflow.contrib.sensors.file_sensor import FileSensor
from airflow.operators.postgres_operator import PostgresOperator
from airflow.operators.python_operator import PythonOperator
import psycopg2

with DAG('Write_data_to_PG', description='This DAG is for writing data to postgres.', schedule_interval='*/5 * * * *',
         start_date=datetime(2018, 11, 1), catchup=False) as dag:
    create_table = PostgresOperator(
        task_id='create_table',
        sql="""CREATE TABLE users(
            id integer PRIMARY KEY,
            email text,
            name text,
            address text
        )
        """,
    )


    def my_func():
        print('Creating table in database.')
        conn = psycopg2.connect("host=localhost dbname=testdb user=testuser")
        print(conn)

        cur = conn.cursor()
        print(cur)

        with open('test.csv', 'r') as f:
            next(f)  # Skip the header row.
            cur.copy_from(f, 'users', sep=',')

        conn.commit()
        print(conn)
        print('DONE!!!!!!!!!!!.')


    file_sensing_task = FileSensor(task_id='sense_the_csv',
                                   filepath='test.csv',
                                   fs_conn_id='my_file_system',
                                   poke_interval=10)

    python_task = PythonOperator(task_id='populate_data', python_callable=my_func)

    create_table >> file_sensing_task >> python_task