1. 程式人生 > >整取零存_欄位級遷移工具

整取零存_欄位級遷移工具

> 6月份的大部分時間在完成一個特殊的資料遷移工具,將檔案中的標籤整合到關係型資料庫的表字段中。從近幾年的技術趨勢和參與的專案看,基本都是從關係型資料庫往大資料元件遷移。在這個專案中,主要是客戶和相關應用的供應商依賴於PostgreSQL的GIS外掛。因此我也有幸使用了一次PostgreSQL資料庫。本文簡要講解了工具開發的背景和難點,並給出了程式邏輯和原始碼連結。 # 01 需求和背景 **a). 為什麼說這是一個欄位級別的遷移?** 作為資料來源的標籤檔案數量非常多,根據標籤的分類和加工的便利程度,有大量含有各位資料標籤列的檔案。而同時在PG庫表中,為了減少join,提升資料庫查詢速度,大量標籤欄位又合在一張表中。結果就是存在,一個檔案的不同列可能對映到不同的表中,一張表的不同欄位來自於不同的檔案。檔案和表存在的是多對多的關係。這就造成不能簡單地做出某個檔案到某張表的對映關係,然後使用匯入工具匯入即可。 同時,對於客戶和使用者而言,他們希望看到的是就是標籤值(即對應資料庫中的欄位)。通過展示標籤級別的對映關係,終端使用者可以知曉每個標籤的業務含義和資料來源;通過展示每個標籤的加工狀態,管理員可以快速獲取整體標籤的可用性。 最後,資料來源結構上是半結構化的csv檔案,列的數量和存放順序可能發生改變。檔案和表的將是動態的,維護起來的工作量也過於巨大。 **b). 開發中依賴的一些業務說明** 首先,對於標籤類資料的存放表,認為是有業務主鍵的,這些主鍵也是其他應用查詢資料時的條件。程式中使用這些主鍵來完成新標籤資料的插入和舊標籤資料的更新。 對於明細類資料,資料來源的定義認為是沒有主鍵的日誌類資料,只有插入的操作無更新的操作。 同時,標籤的更新方式還分為增量和全量。增量即常規的merge操作,而全量方式需要將表中的指定標籤欄位置空後再進行merge操作。 # 02 遇到的問題和解決方法 **a). 檔案的匯入和併發控制** 雖然每一個任務都是欄位級別操作的,但是對於資料來源檔案的匯入存在多個標籤對應同一原始檔的情況,所以在檔案匯入操作上有一個專門的狀態表記錄檔案匯入的狀態。如果有其它標籤任務在執行相同的檔案匯入了,狀態就會變成`processing`。作為一個後來的任務,必須等待狀態為`success`或者`fail`時才能進行檔案的再次匯入。 同時為了避免檔案的再次匯入,每次匯入還會比較HDFS中檔案的時間戳和狀態表中的時間戳,如果時間戳一致,則直接使用已匯入的檔案即可。 **b). 檔案的動態入庫** csv檔案的首行列名作為欄位名,檔名作為表明在臨時庫建立一張臨時表,然後使用`copy_expert`函式避免雙引號分界符內容中存在逗號的問題。 **c). 明細和標籤的整合** 為了讓兩者使用同一套欄位級別的merge方法,對於明細的資料在傳到本地檔案系統後,呼叫shell命令根據每一行的內容加行號md5 hash之後作為一行明細的主鍵。從而每一行資料都是唯一的,保證了資料在呼叫merge操作時只有insert行為。 **d). 派生欄位的處理** 這裡的派生欄位是指,在原檔案的列名中包含了一層資料,比如說同一個檔案存在一列名「甲品牌_銷售額」和「乙品牌_銷售額」,而最終的標籤需求為「銷售額」,「品牌」。即一列將變成兩列,同時資料行數將變成原有行數的(品牌列舉值個數)倍。 這個擴充套件的操作,是在原始檔入臨時庫之後,通過遍歷「品牌」列舉值,將其它列資料進行`union all`操作實現。 **e). 欄位型別轉換** 因為原始檔案匯入都是以文字形式入庫,實際標籤值可能有數字、布林、地理座標等型別,需要有一個專門的函式對標籤值進行型別轉換操作。 **f). PostgreSQL中的merge操作** 在PostgreSQL中,merge操作通過`insert into on conflict () do update set = excluded.`實現。 # 工具的處理邏輯 ![etl_flow](https://img2020.cnblogs.com/blog/670593/202007/670593-20200706220100430-1216355170.png) # 程式碼和遺留問題 程式碼github連結[github](https://github.com/camash/tag_level_etl) **遺留問題:** 1. 對於主鍵的要求的強制的,但是程式沒有主動去目標表中增加主鍵; 2. 對於派生欄位只能提供增加一個欄位,不支援多個; 3. 在幾千條資料來源情況下,單個標籤匯入的時間為2秒左右,未對千萬級資料來源做效能測試; 4. 未提供多標籤同時匯入的介面 5. 執行資訊用了print()列印在螢幕,需要使用log模組優化輸出和分類。 # 總結 本文分享近期開發的一個標籤/欄位級別資料遷移的工具,通過Python實現。介紹了工具的一些背景和實現的一些難點。同時分享了工具的核心程式碼,拋磚引玉,希望跟有興趣的同學共同探討更高效的實現方式。 **歡迎掃描二維碼關注公眾號** ![](https://img2018.cnblogs.com/blog/670593/201912/670593-20191201214002980-30853