最近接手一個項目,程序的基本框架是:程序A導出數據,以.tsv格式存儲,數據列之間以tab間隔;程序B吃文檔,把數據導入到數據庫中,並把處理過的文檔備份/移動到指定的目錄中。為了快速開發,程序B設計成SSIS的Package,本文主要分享Package的設計思路,組件用法和注意事項。在設計Package時,使用Foreach Loop Container組件遍歷Folder中存儲的.tsv文檔,通過平面文件源讀取遍歷的tsv文件,通過Expression Task組件獲得該文件的備份路徑,通過File System Task把處理過的文件移動到指定的目錄中,該Package主要用到四個組件,分別是,Flat Files Source,Expression Task和 File System Task,Package的設計核心簡化為下圖所示:
一,遍歷目錄
導入文檔內容的第一步是遍歷目錄,讀取文件的路徑,這一步可以通過Foeach Loop Container組件實現。打開Collection選項卡,如下圖,從枚舉器(Enumerator)列表中選擇“Foreach File Enumerator”,枚舉器的配置界面如下圖:
- Folder:指定遍歷的目錄
- Files:指定文件名模式,示例是 *.tsv,代表文件名以.tsv結尾的所有文件,其中通配符*代表任意字符;
- Retrieve file name:獲取文件名的模式,默認選項是完全限定名(Full qualified),格式是:虛擬盤符+目錄+文件名+文件擴展名;
- Traverse Subfolders:如果勾選遍歷子文件夾,那么文件遍歷器將會遍歷Folder下的子目錄。
枚舉器的配置屬性,都可以通過Expressions屬性來配置,屬性表達式的配置界面如下圖:
在變量映射(Variable Mappings)選項卡中,選擇變量User::DataFilePath,用於臨時存儲每次遍歷獲取的文件名:
如果指定的目錄下,沒有存儲任何文件,那么遍歷循環容器(Foreach Loop Container)直接返回,不會指定其容納的任何Task。
二,平面文件源
平面文件源(Flat File Source)用於從指定的路徑中讀取文件,並按照指定的界定符讀取數據,把具有特定格式的平面文件轉換成關系表,平面文件的格式界定符分為:列分隔符和行分隔符,通常,tsv文件的列分隔符是tab,列分隔符是回車+換行。本來的目的,平面文件是動態變化的,不能指定文件的路徑,在設計時,卻必須初始化設計平面文件連接管理器的元數據,因此,首先,必須寫Hard Code,在連接管理器中指定一個文件的路徑;然后設置表達式屬性,通過變量來設置平面文件連接管理器的外部數據源,也就是,源平面文件。SSIS組件有一個共性,那就是,在表達式(Expressions)中指定的屬性值,會覆蓋相同屬性直接指定的值。通過硬編碼方式指定源文件,僅僅是為了提供源平面文件的格式元數據,不會影響Package的執行。
1,創建平面文件連接管理器
在File Name中指定平面文件的路徑,選擇平面文件的Locale,默認是English,勾選Unicode,表示平面文件以Unicode編碼存儲。
在General選項卡中,配置常規屬性:
- 平面文件的格式(Format)是:Delimited,以界定符分割。
- Text qualifier:文本界定符,用於指定文本以什么符號分割,默認值是<none>,表示文本沒有界定符;
- Header row delimiter:首行界定符,默認值是回車+換行;
- Header rows to skip:文本的第一行,需要從文檔開頭跳過多少行,默認值是0,也就是說,文檔的第一行是文本的第一行;
- Column names in the first data row:勾選,表面數據的第一行是列名;
在Columns選項卡中,配置列屬性:
- Row delimiter:配置行分隔符,通常選擇{CR}{LF},兩行之間以回車+換行分割;
- Column delimiter:配置列分隔符,通常選擇Tab {t},兩列之間以制表符分割;
在Advanced選項卡中,配置外部數據列的屬性:
- Name:配置列名
- ColumnDelimiter:列分隔符
- DataType:列值的數據類型,如果勾選Unicode,那么輸出列數據類型的默認值是Unicode string [DT_WSTR],否則,默認值是string [DT_STR];
- OutputColumnWidth:輸出列的長度,默認值是50;
- TextQualified:文本界定,指定是否文件數據被文本界定符(例如,引號)圍繞,默認值是True;
默認情況下,平面文件連接管理器把字符串字段的長度設置為50個字符,但是,當列的分割不是以字符數量,而是以分割符(Tab,制表符)來界定時,你需要根據文檔中字段的實際長度來預估和設置各個數據列的長度,以避免發生數據截斷,或者超出字段設置的寬度而引發的異常。
2,創建平面文件源
打開平面文件源組件,在Connection Manager選項卡中指定已創建的平面文件連接管理器,在Columns選項卡中查看所有可用的外部數據列,在Error Output選項卡中,當外部列轉換成輸出列出現異常時,指定組件對對轉換錯誤的處理模式。
通常情況下,勾選"Retain null values from the source as null values in the data flow",保持數據源的null值。
3,使用平面文件連接管理器的Expressions屬性
在連接管理器(Connection Managers)窗體中,選中平面文件連接管理器,打開屬性(Properties),配置表達式屬性。
選中Expressions屬性,點擊后面的“...”,彈出屬性表達式編輯器,
在屬性表達式編輯器中,有一個屬性表達式表格,有Property列和Expression列,Property列是一個列表,Expression列是表達式生成器(Builder),為了逐個讀取指定目錄下的文件,從Property列表中,選擇連接字符串(ConnectionString)屬性,並在Expression列中選中變量@[User::DataFilePath],這樣,每次遍歷,平面文件連接管理器都會連接到變量指定的文件,讀取數據,按照已設置的元數據向下游組件輸出。
三,表達式任務組件
指定表達式,根據當前文件的路徑,修改為備份的目的目錄,注意,應該指定移動到的目錄(Destination Directory),而不是文件的完全限定名:
四,文件系統任務
文件系統任務,用於對文件進行操作,其配置界面如下圖,操作類型由屬性Operation指定,本例是為了把文本備份到指定的目錄中,選中操作類型為:Move file
文件系統任務,主要屬性是:Source Connection,Destination Connection 和 Operation,分別是:
- Source Connection:源連接,用於操作的源文件路徑;設置屬性IsSourcePathVariable為True,可以通過變量指定源文件路徑;
- Operation:操作類型,共有:
- 復制目錄(Copy directory),
- 復制文件(Copy file),
- 創建目錄(Create directory),
- 刪除目錄(Delete directory),
- 刪除目錄內容(Delete directory content),
- 刪除文件(Delete file),
- 移動文件(Move file),在移動文件時,目標目錄必須存在。
- 重命名文件(Rename file),
- 設置屬性(Set properties)
- Destination Connection:目標連接,用於指定操作的目標目錄的路徑;設置屬性IsDestinationPathVariable為True,可以通過變量指定目標目錄;屬性OverwriteDestination用於指定,當目標文件已存在時,是否重寫目標文件。
注意,在移動文件(Move File)時,需要指定目標目錄(Destination Directory),SSIS對目標連接的定義如下:
如果指定的是文件的完全限定名,或目標目錄不存在,文件系統任務會報錯:
An error occurred with the following error message:"Could not find a part of the path."
五,重要屬性
在本例中,有一個非常重要的屬性必須配置,那就是延遲驗證(DelayValidation)屬性,該屬性表示可執行組件的驗證延遲到運行時,為什么要延遲到運行時呢?這是因為在設計Package時使用動態賦值的特性,有一些變量的值,或者表達式的值,只有在Package運行時,才會真正賦值。基本上每個Task組件都有延遲驗證(DelayValidation)屬性,其默認值是False,雙擊切換為True,啟用組件的延遲驗證。
1,啟用文件系統任務
在配置完成之后,文件系統任務會拋出錯誤提示,錯誤消息是:Variable "DataFilePath" is used as a source or destination and is empty.
這是因為變量未被賦值,而文件系統任務組件探測(Detect)到引用的文件不存在,所以拋出異常消息,為了避免出現運行時錯誤,開啟延遲驗證,把可執行組件的驗證推遲到執行時,需要設置文件系統任務的屬性,把延遲驗證(DelayValidation)屬性設置為True。
2,啟用Container和Data Flow Task的延遲驗證
六,WMI 事件監控任務
WMI 事件監控任務(WMI Event Watcher Task)是一個非常神秘的任務組件,創建WMI Connection,輸入WQL命令:
在WqlQuerySource中輸入WQL命令,該命令表示:監控指定的目錄,當有新文件插入后,該組件執行成功,否則,一直輪詢。
SELECT * FROM __InstanceCreationEvent WITHIN 10 WHERE TargetInstance ISA "CIM_DirectoryContainsFile" and TargetInstance.GroupComponent= "Win32_Directory.Name=\"D:\\\\DataFromCosmos\\\\MSCommunity\\\\MSCommunity_Posts\""
本例沒有用到該組件,僅僅為了多了解一些組件的基本用法。
參考文檔:
Using the WMI Event Watcher Task in SSIS to Process Data Files