簡體   English   中英

Airflow:無法將數據從 myql 數據庫傳輸到 csv 文件

[英]Airflow: Not able to transfer data from myql database to csv file

我正在處理 Airflow,我正在嘗試將數據從 mysql 數據庫傳輸到 csv 文件。 下面是代碼和函數

from airflow import DAG
from datetime import datetime,timedelta
from airflow.operators.bash_operator import BashOperator
from airflow.operators.python_operator import PythonOperator
from airflow.operators.mysql_operator import MySqlOperator

from dbextract import extract_data
from dbpost_processing import dbpost_process

default_args = {"owner":"airflow","start_date":datetime(2021,7,10)}
with DAG(dag_id="dbworkflow2",default_args=default_args,schedule_interval=None) as dag:
   
    extract = MySqlOperator(
        task_id='extract',
        mysql_conn_id="mysql_db1", 
        sql = extract_data
        )
        
    dbpost_process = PythonOperator(
        task_id = "dbpost_process",
        python_callable = dbpost_process
        )   
        
    extract >> dbpost_process
import pandas as pd
def extract_data():
    df=pd.read_sql('SELECT * FROM new_table', mysql_conn_id)
import pandas as pd
def dbpost_process():
    df.to_csv('~/op_files/sample3.csv', index=False)

獲取錯誤 function object 在 extract_data 步驟中不可迭代

MySQL 文件中的 sql 不是可調用的,它應該是字符串或字符串列表。 您還試圖在任務之間傳遞 panda dataframe 並且它不會工作,因為任務可能(並且很可能會)在不同進程中的不同機器上運行。

任務之間交換數據的方式通常是通過 XComs(對於少量數據,它應該通過 DB,對於大量數據,您可以添加自定義 XCom 后端並通過例如 S3 或 GCS 傳遞數據)。

但是,在您的情況下,您不需要有兩個單獨的任務/操作員。 相反,您應該在 Python 運算符內部使用 MySQL Hook 來讀取數據並在相同的任務中處理它。 將該作業拆分為兩個單獨的任務是沒有意義的 - MySQL Operator 實際上是執行 DDL 或 DML 操作,而不是提取數據(正是因為 Airflow Operator 是孤立工作的)

Airflow 取而代之的是提供 API 的 Hooks 概念,您可以使用它在同一個 Python 可調用運算符中運行查詢和處理數據。 甚至最近它都可以使用 @task 裝飾器來完成,因此它非常簡單並且更容易編寫 - 特別是如果您習慣於編寫函數式 Python。

參見https://airflow.apache.org/docs/apache-airflow/stable/tutorial_taskflow_api.html

但在你的情況下,你甚至不需要這樣做,因為你想使用pandas與 MySQL db 進行通信,所以你甚至不需要使用 Hook。 這樣的東西就足夠了。 在這種情況下你不應該使用 conn_id,但你需要在那里傳遞一個 SQL-Alchemy 兼容的連接字符串。 不確定 Airflow 連接 url 是否有效,但如果有效,那么您可以使用Connection.get_uri() (也許您需要稍微調整一下 URI)。

類似的東西(這對你來說是一種靈感,而不是可編譯的代碼,所以你需要弄清楚細節)應該可以工作:

@dag(default_args=default_args, schedule_interval=None, start_date=days_ago(2))
def my_dag():
    @task()
    def my_extraction():
         df =  pd.read_sql('SELECT *', Connnection.get("my_connection_id").get_uri()) 
         file = post_process(df)

現在 - 你還必須對該文件做一些事情,因為一旦任務完成,本地數據將不可用(除非你使用 LocalExecutor) - 你可以將 CSV 發送到某處(為此你可以使用任何 Hook -例如 S3Hook)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM