分享方式:


TripPin 第 4 部分 - 數據源路徑

此多部分教學課程涵蓋如何建立Power Query的新數據源延伸模組。 本教學課程旨在循序完成,每個課程都是以先前課程中建立的連接器為基礎,以累加方式將新功能新增至您的連接器。

在本課程中,您將會:

  • 簡化連接器的連接邏輯
  • 改善瀏覽數據表體驗

本課程藉由移除其必要的函式參數,並移至動態產生的瀏覽數據表來改善用戶體驗,藉此簡化上一課建的連接器。

如需如何識別認證的深入說明,請參閱處理驗證數據源路徑一節。

數據源路徑

用數據源函式時,M 引擎會根據 數據源種類數據源路徑 值執行查閱,來識別評估期間要使用的認證。

在上一個課程,您已共用兩個數據源函式,兩者都是使用單一 Uri.Type 參數。

[DataSource.Kind="TripPin"]
shared TripPin.Feed = Value.ReplaceType(TripPinImpl, type function (url as Uri.Type) as any);

[DataSource.Kind="TripPin", Publish="TripPin.Publish"]
shared TripPin.Contents =  Value.ReplaceType(TripPinNavTable, type function (url as Uri.Type) as any);

第一次執行使用其中一個函式的查詢時,您會收到包含下拉式清單的認證提示,可讓您選取路徑和驗證類型。

具有路徑的認證。

如果您再次使用相同的參數執行相同的查詢,M 引擎就能夠找到快取的認證,而且不會顯示任何認證提示。 如果您將 url 自變數修改為函式,讓基底路徑不再相符,則會針對新路徑顯示新的認證提示。

您可以在 [M 查詢輸出] 視窗中的 [認證] 資料表上看到任何快取的認證。

[認證] 索引標籤。

視變更類型而定,修改函式的參數可能會導致認證錯誤。

簡化連接器

您現在會移除數據源函式的參數,以簡化連接器。TripPin.Contents 您也會移除 的sharedTripPin.Feed限定符,並將它保留為僅限內部的函式。

Power Query 的設計理念之一是盡可能讓初始數據源對話框保持簡單。 如果可能的話,您應該在 [導覽器] 層級提供選項給使用者,而不是在 [連線] 對話框中提供選擇。 如果可以程式設計方式判斷使用者提供的值,請考慮將其新增為瀏覽數據表的最上層,而不是函式參數。

例如,連接到關係資料庫時,您可能需要伺服器、資料庫和數據表名稱。 一旦您知道要連線的伺服器,並提供認證之後,您就可以使用資料庫的 API 來擷取資料庫清單,以及每個資料庫中包含的數據表清單。 在此情況下,若要盡可能讓初始連線對話框保持簡單,只有伺服器名稱應該是必要的參數,Database 而且 Table 會是瀏覽數據表的層級。

由於 TripPin 服務具有固定的 URL 端點,因此您不需要提示使用者輸入任何值。 您將從函式中移除 URL 參數,並在連接器中定義 BaseUrl 變數。

BaseUrl = "https://services.odata.org/v4/TripPinService/";

[DataSource.Kind="TripPin", Publish="TripPin.Publish"]
shared TripPin.Contents = () => TripPinNavTable(BaseUrl) as table;

您將保留函 TripPin.Feed 式,但不再將其共用,不再將它與數據源種類產生關聯,並簡化其宣告。 從這一點開始,您只會在本節文件內部使用它。

TripPin.Feed = (url as text) =>
    let
        source = Web.Contents(url, [ Headers = DefaultRequestHeaders ]),
        json = Json.Document(source)
    in
        json;

如果您在檔案中TripPin.query.pq更新TripPin.Contents()呼叫,並在 Visual Studio Code 中執行該呼叫,您會看到新的認證提示。 請注意,現在有單一數據源路徑值 — TripPin。

沒有路徑的認證。

改善瀏覽數據表

在第 一個教學課程中 ,您已使用內 OData 建函式來連線到 TripPin 服務。 這可讓您根據 TripPin 服務檔提供美觀的導覽表格,且您的端沒有更多程式代碼。 OData.Feed 函式會自動為您執行工作。 由於您使用 Web.Contents 而非 OData.Feed 來「粗略」,因此您必須自行重新建立此瀏覽數據表。

OData Navigator。

您將進行下列變更:

  1. 定義要顯示在導覽表中的項目清單
  2. 不要使用實體特定函式 (GetAirlineTablesGetAirportsTable

從清單產生導覽數據表

您將列出要在導覽表中公開的實體,並建置適當的URL來存取它們。 由於所有實體都位於相同的根路徑下,因此您可以動態建置這些 URL。

為了簡化此範例,您只會公開三個實體集 (Airlines, Airports, People),這會公開為 M 中的數據表,並略過會公開為 Record 的單一實體集 (Me)。 您將略過新增函式,直到稍後的課程為止。

RootEntities = {
    "Airlines",
    "Airports",
    "People"
};

接著,您會更新函 TripPinNavTable 式,一次建置一個數據行。 呼叫實體的完整 URL,以擷取 TripPin.Feed 每個實體的 [數據] 資料行。

TripPinNavTable = (url as text) as table =>
    let
        entitiesAsTable = Table.FromList(RootEntities, Splitter.SplitByNothing()),
        rename = Table.RenameColumns(entitiesAsTable, {{"Column1", "Name"}}),
        // Add Data as a calculated column
        withData = Table.AddColumn(rename, "Data", each TripPin.Feed(Uri.Combine(url, [Name])), Uri.Type),
        // Add ItemKind and ItemName as fixed text values
        withItemKind = Table.AddColumn(withData, "ItemKind", each "Table", type text),
        withItemName = Table.AddColumn(withItemKind, "ItemName", each "Table", type text),
        // Indicate that the node should not be expandable
        withIsLeaf = Table.AddColumn(withItemName, "IsLeaf", each true, type logical),
        // Generate the nav table
        navTable = Table.ToNavigationTable(withIsLeaf, {"Name"}, "Name", "Data", "ItemKind", "ItemName", "IsLeaf")
    in
        navTable;

動態建置 URL 路徑時,請確定您清楚正斜線的位置(/) 是! 請注意, Uri.Combine 在合併路徑時會使用下列規則:

  • relativeUri當參數以 /開頭時,它會取代參數的baseUri整個路徑
  • relativeUri如果 參數不是以 / 開頭,並以 baseUri /結尾,則會附加路徑
  • relativeUri如果 參數不是以 / 開頭,且baseUri結尾不是 /,則會取代路徑的最後一個區段

下圖顯示下列範例:

Uri.Combine 範例。

拿掉實體特定函式

為了讓連接器更容易維護,您將移除您在上一課中使用的實體特定格式函式,GetAirlineTablesGetAirportsTable。 相反地,您將更新 TripPin.Feed 以處理 JSON 回應的方式,讓所有實體都能運作。 具體而言,您會取得 value 傳回 OData JSON 承載的欄位,並將它從記錄清單轉換成數據表。

TripPin.Feed = (url as text) =>
    let
        source = Web.Contents(url, [ Headers = DefaultRequestHeaders ]),
        json = Json.Document(source),
        // The response is a JSON record - the data we want is a list of records in the "value" field
        value = json[value],
        asTable = Table.FromList(value, Splitter.SplitByNothing()),
        // expand all columns from the record
        fields = Record.FieldNames(Table.FirstValue(asTable, [Empty = null])),
        expandAll = Table.ExpandRecordColumn(asTable, "Column1", fields)
    in
        expandAll;

注意

使用一般方法來處理實體的缺點是,您會失去實體的不錯格式和類型資訊。 本教學課程稍後的章節說明如何在 REST API 呼叫上強制執行架構。

結論

在本教學課程中,您已藉由修正數據源路徑值,並移至更彈性的導覽數據表格式,來清除和簡化連接器。 完成這些步驟之後(或使用此目錄中的範例程式代碼),函 TripPin.Contents 式會傳回 Power BI Desktop 中的導覽數據表。

導覽。

下一步

TripPin 第 5 部分 - 分頁