logo头像

Edward.K Thinking

Azure Data Factory判斷Azure Data Lake的檔案/路徑是否存在

我們可以透過ADF不斷讀取Azure Data Lake內的檔案進行處理,不過,今天在ADF中,我們設定讀取Azure Data Lake的檔案路徑是透過Dynamic Content方式定義的時候,就必須注意到一件事情就是檔案或是資料夾是否存在,不然會出現找不到檔案的錯誤,如果,其中有又在ADL(Azure Data Lake)設定資料夾做分類,且Dynamic Content又是在針對資料夾去變化,如下:

如果當這規則成立時候,但是ADL內並沒有這樣的資料夾,就最發生下面這類型錯誤

Activity AlarmFolderExists failed: Field ‘size’ failed with error: ‘Type=Microsoft.DataTransfer.Common.Shared.HybridDeliveryException,Message=Cannot find the ‘Azure Data Lake Store’ file. . Service request id: c733cba6-3854-471c-b287-2b8d1918d673 Response details: {“RemoteException”:{“exception”:”FileNotFoundException”,”message”:”File/Folder does not exist:

主要就是它找不到路徑,要解決這問題,就必須在讀取資料前,先去判斷這個路徑或是資料夾是否存在,做法就是必須在ADF的Copy Data前加入一個Get Metadata Task

加入MetaData


只加入MetaData就可以嗎?當然不是,必須針對MetaData出來的結果,做出判斷來決定後續的動作要怎樣執行。以這邊案例來說就是當沒有ADF中的路徑或是檔案不存在時候,就不需要執行Copy Data的動作。其流程如下

首先要先加入一個Get MetaData,加入MetaData後,就是設定你要針對那一個資料集去做判斷,其中最重要的就是在Field List的設定

Field List可設定的有下面這些,不過會根據你所選的資料集類型的不同,可用的類型也會有所不同

這些類型意義分別如下:

  • itemName:檔案或資料夾的名稱。
  • itemType:檔案或資料夾的類型。 輸出值是 File 或 Folder。
  • size:檔案的大小。 僅適用於檔案。
  • created:檔案或資料夾的建立日期時間。
  • lastModified:檔案或資料夾的上次修改日期時間。
  • childItems:所指定資料夾內子資料夾和檔案的清單。 僅適用於資料夾。 輸出值為每個子項目的名稱和類型清單。
  • contentMD5:檔案的 MD5。 僅適用於檔案。
  • structure:檔案或關聯式資料庫資料表內的資料結構。 輸出值為資料行名稱和資料行類型的清單。
  • columnCount:檔案或關聯式資料表內的資料行數目。
  • exists:檔案/資料夾/資料表存在與否。

這個案例中,只需要判斷資料夾是否存在,所以只需要在Field List中設定exists,就可以。不過呢,這邊有一個很大的坑,就在是在於你如果設定是exists,它會取決於ADF DataSet中的File path來判斷,舉例來說

第一種設定方式

1
File Path : @concat('/XX/XXX/XXX/',dataset().FileDataPath)/* 或是 @concat('/XX/XXX/XXX/',dataset().FileDataPath)/?A.csv

對於Get MetaData的判斷就會認定是要去判斷檔案是否存在,且檔案名稱就是*或是?A.csv,想當然這是不對的,但對於ADL抓檔案來說這確實合理的,可以針對這個路徑下所有的檔案或是檔名後面有A的進行抓取,不過重點在於這邊我們需要是判斷路徑是否存在,這樣就會導致Get MetaData去判斷檔案是否存在,所以必須要在ADL DataSet改成這樣

1
File Path : @concat('/XX/XXX/XXX/',dataset().FileDataPath)/

換句話說,就是在ADL DataSet的File Path的檔案那個空格不能有加任何字元,這樣Get MetaData就知道是要判斷資料夾了,但這樣ADL也可以抓取這個資料夾下的所有檔案,所以,影響性並不大,也才能讓Get MetaData可以成功執行

設定If Condition


設定好Get MetaData再來就是設定If Condition,由上面可以知道If Condition判斷結果會是這樣

1
2
3
4
5
{
"exists": false,
"effectiveIntegrationRuntime": "DefaultIntegrationRuntime (Central US)",
"executionDuration": 522
}

如果沒有資料夾就會顯示false,有就會顯示ture,然後,我們就利用這樣結果放入到If Condition,要取得這樣結果要用這樣參數

1
@bool(activity('Get MetaData的名字').output.Exists)

放在If Condition的Setting

然後再去設定If Condition的Activities,看是True要執行甚麼動作,False要執行甚麼動作

上一篇