python ETL工具

應對小規模業務場景使用專業的etl會有點費勁,還得增加運維監控成本,想想直接寫個框架,用代碼直接做etl數據接入

安裝

pip install pyetl

使用

首先看下最簡單的demo

from pyetl import Etl
class TestConfig:
    # 這裏直接是把源庫和目的庫配置成了一個,只是爲了演示使用
    DST_URI = SRC_URI = {'uri': 'mysql+pymysql://root:hadoop@localhost:3306/test'}
# 'test_src'和'test_dst'分別是源表名稱和目的表名稱
app = Etl('test_src', 'test_dst')
app.config(TestConfig)
app.run()

我們正常的業務需求肯定比這個複雜的多,這就涉及轉換操作,這裏的處理方式是添加udf函數
最簡單的數據轉換,比如某個字段全部大寫處理(下面以id字段爲例,一般不可能有這種簡單的轉換,這裏只做演示)

app = Etl('src_table', 'dst_table', unique='id') # unique這個參數作用是確定唯一鍵,數據插入時會做merge操作
app.config(TestConfig)
@app.add('id')(lambda x:x.upper()) # add(參數可以是str或list) 可以向任務註冊某個或某幾個字段的轉換函數,可以是一個字段分解爲多個字段,也可以是多個字段合併爲一個字段
@app.befor(lambda app:app.dst.empty('dst_table')) # befor 函數是在開始一次etl前的預處理操作
@app.after(lambda app:app.dst.empty('src_table')) # after 函數是在一次etl完成後的掃尾操作
app.run(where='limit 10') # 這裏where可以對數據源做數據篩選過濾過濾

下面是增量更新場景

mapping = {'id': 'id_code'} 
# mapping是當源庫和目的庫之間表字段不一致時配置的映射關係(key是目的庫字段名,value是源庫字段名,value可以是list表示兩個字段合併到目的字段,怎麼合併需要用add註冊具體的處理函數)
# src_update爲更新標誌字段(是源庫的字段名),每次拉取數據都會記錄時間點
app = Etl('src_table', 'dst_table', mapping=mapping, unique='id', src_update='update_time')
app.config(TestConfig)
app.run(days=1) # 這裏的days作用是在原來更新時間點的基礎上向前推days天,days爲0時忽虐src_update字段記錄的時間直接全表接入

創建項目

這裏提供了一個簡單的項目結構做參考,直接使用pyetl命令行生成一個簡單的項目結構,其中的job.py就是我們的etl任務,數據庫配置都在config.py裏,根據實際環境添加
pyetl -b [project name]
項目結構

以上命令創建好一個工程文件,需要根據個人環境進行配置,下面是一些參數說明
app/config.py文件(主要是SRC_URI和DST_URI參數)
    SRC_URI(源庫配置)
    DST_URI(目的庫配置)
    SRC_PLACEHOLDER(數據源驅動的佔位符形式, 以sqlalchemy連接形式配置時不需要關注)
    QUERY_SIZE(單次獲取數據量,根據實際環境機器性能,可以不關注)
    INSERT_SIZE(單次插入數據量,根據實際環境機器性能,可以不關注)

app/etl/job.py文件,單個etl任務示例(主要是src_tab和dst_tab參數)
    src_tab(源表名稱)
    dst_tab(目的表名稱)
    mapping(可選關鍵字參數,目的表到源表的字段映射,當源表和目的表字段名稱不一致是使用)
    src_update(可選關鍵字參數,源表的數據更新標誌,只要是增長類型的都可以,比如數據變更時間字段,非空以增量形式插入)
    dst_unique(可選關鍵字參數,目的表的唯一鍵,非空以merge形式插入)

由於不同數據庫驅動配置的形式都會不一樣,因此這裏統一的都採用字典的形式配置的,下面以連接impala爲例:
DST_URI = {
‘host’: ‘192.168.1.1’,
‘port’: 21050,
‘use_kerberos’: True,
‘kerberos_service_name’: ‘impala’,
‘timeout’: 3600,
‘driver’: ‘impala.dbapi’,
}
這裏要在原有impala驅動參數配置的基礎上增加driver參數,來讓代碼識別對應的數據庫驅動程序,沒辦法python沒有像java一樣統一的jdbc,這裏可以參考下我的pydbclib的設計,勉強統一了下python數據庫操作
另外也做了數據庫和csv類型的文件間的轉換,不過一般很少用,所以就跳過吧

項目地址: pyetl

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章