通过


管理转换过程

对于未以 Power BI 可以直接使用的格式显示数据源响应的情况,可以使用 Power Query 来执行一系列转换。

静态转换

在大多数情况下,数据源以一致的方式呈现数据:列名、数据类型和分层结构对于给定终结点是一致的。 在这种情况下,应始终应用相同的转换集来获取 Power BI 可接受的格式的数据。

当数据源被视为标准 REST 服务时,可以在 TripPin 第 2 部分 - REST 服务的数据连接器 教程中找到静态转换的示例:

let
    Source = TripPin.Feed("https://services.odata.org/v4/TripPinService/Airlines"),
    value = Source[value],
    toTable = Table.FromList(value, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
    expand = Table.ExpandRecordColumn(toTable, "Column1", {"AirlineCode", "Name"}, {"AirlineCode", "Name"})
in
    expand

此示例中的转换如下:

  1. Source 是从调用TripPin.Feed(...) 返回的一条记录。
  2. Source的某个键值对中提取值。 键的名称是value,结果存储在名为value的变量中。
  3. value 是一个列表,可转换为表。 每个 value 元素都会成为表中的一行,你可以将该表称为 toTable
  4. 每个元素 value 本身都是一个 Record。 toTable在单个列中具有所有这些项: "Column1" 此步骤将具有键"AirlineCode"的所有数据提取到名为"AirlineCode"的列中,并将具有键"Name"的所有数据提取到名为"Name"的列中,针对toTable中的每一行。 "Column1" 被替换为这两个新列。

在一天结束时,你留下的数据采用简单的表格格式,Power BI 可以使用并轻松呈现:

表格格式的数据的屏幕截图。

请务必注意,此特定性的静态转换序列仅适用于 单个 终结点。 在前面的示例中,此转换序列仅在 REST 终结点响应中存在时才"AirlineCode""Name"起作用,因为它们已硬编码为 M 代码。 因此,如果尝试访问/Event该终结点,那么此转换序列可能不起作用。

将数据推送到导航表可能需要这种高度的针对性。 但是,对于更常规的数据访问函数,我们建议你仅执行适合所有终结点的转换。

注释

请务必在各种数据情况下测试转换。 如果用户在终结点上 /airlines 没有任何数据,转换是否会导致具有正确架构的空表? 还是评估期间遇到错误? 有关单元测试的讨论 ,请参阅 TripPin 第 7 部分:具有 M 类型的高级架构

动态转换

有时需要更复杂的逻辑,以便将 API 响应转换为适合 Power BI 数据模型的稳定且一致的形式。

API 响应不一致

基本的 M 控制流(如 if 语句、HTTP 状态代码、try...catch 块 等等)通常足以处理 API 响应的几种情况。

动态确定架构

某些 API 设计为必须组合多个信息片段才能获取正确的表格格式。 考虑 Smartsheet 的 /sheets终结点响应,其中包含列名数组和数据行数组。 Smartsheet 连接器能够以以下方式分析此响应:

raw = Web.Contents(...),
columns = raw[columns],
columnTitles = List.Transform(columns, each [title]),
columnTitlesWithRowNumber = List.InsertRange(columnTitles, 0, {"RowNumber"}),
                
RowAsList = (row) =>
    let
        listOfCells = row[cells],
        cellValuesList = List.Transform(listOfCells, each if Record.HasFields(_, "value") then [value]
                else null),
        rowNumberFirst = List.InsertRange(cellValuesList, 0, {row[rowNumber]})
    in
        rowNumberFirst,

listOfRows = List.Transform(raw[rows], each RowAsList(_)),
result = Table.FromRows(listOfRows, columnTitlesWithRowNumber)
  1. 首先处理列标题信息。 可以将每个列的title记录提取到列表中,并在前面添加一个RowNumber列,该列始终作为第一列表示。
  2. 接下来,可以定义一个函数,该函数允许将行分析为单元格 value列表。 可以再次追加 rowNumber 信息。
  3. RowAsList() 函数应用于 API响应返回的每个 row元素。
  4. 将列表转换为表,指定列标题。