TripPin 第 3 部分 - 导航表
本教程分为多个部分,介绍如何针对 Power Query 创建新数据源扩展。 本教程按顺序进行,每一课都建立在前几课创建的连接器的基础上,逐步为连接器添加新功能。
在本课中,你将:
- 为一组固定查询创建导航表
- 在 Power BI Desktop 中测试导航表
本课将导航表添加到上一课中创建的 TripPin 连接器。 连接器使用 OData.Feed
函数(第 1 部分)时,你“免费”获得了从 OData 服务的 $metadata 文档导出的导航表。 当你使用 Web.Contents
函数时(第 2 部分),你就失去了内置导航表。 在本课中,将使用在 Power BI Desktop 中创建的一组固定查询,并为 Power Query 添加适当的元数据,以弹出数据源函数的导航器对话框。
有关使用导航表的详细信息,请参阅导航表文档。
在连接器中定义固定查询
REST API 的简单连接器可以视为一组固定的查询,每个查询返回一个表。 这些表可通过连接器的导航表发现。 基本上,导航器中的每个项都与特定的 URL 和一组转换相关联。
首先,将在 Power BI Desktop 中编写的查询(上一课中)复制到连接器文件中。 在 Visual Studio Code 中打开 TripPin 项目,并将航空公司和机场查询粘贴到 TripPin.pq 文件中。 然后,可以将这些查询转换为采用单个文本参数的函数:
GetAirlinesTable = (url as text) as table =>
let
source = TripPin.Feed(url & "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;
GetAirportsTable = (url as text) as table =>
let
source = TripPin.Feed(url & "Airports"),
value = source[value],
#"Converted to Table" = Table.FromList(value, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
#"Expanded Column1" = Table.ExpandRecordColumn(#"Converted to Table", "Column1", {"Name", "IcaoCode", "IataCode", "Location"}, {"Name", "IcaoCode", "IataCode", "Location"}),
#"Expanded Location" = Table.ExpandRecordColumn(#"Expanded Column1", "Location", {"Address", "Loc", "City"}, {"Address", "Loc", "City"}),
#"Expanded City" = Table.ExpandRecordColumn(#"Expanded Location", "City", {"Name", "CountryRegion", "Region"}, {"Name.1", "CountryRegion", "Region"}),
#"Renamed Columns" = Table.RenameColumns(#"Expanded City",{{"Name.1", "City"}}),
#"Expanded Loc" = Table.ExpandRecordColumn(#"Renamed Columns", "Loc", {"coordinates"}, {"coordinates"}),
#"Added Custom" = Table.AddColumn(#"Expanded Loc", "Latitude", each [coordinates]{1}),
#"Added Custom1" = Table.AddColumn(#"Added Custom", "Longitude", each [coordinates]{0}),
#"Removed Columns" = Table.RemoveColumns(#"Added Custom1",{"coordinates"}),
#"Changed Type" = Table.TransformColumnTypes(#"Removed Columns",{{"Name", type text}, {"IcaoCode", type text}, {"IataCode", type text}, {"Address", type text}, {"City", type text}, {"CountryRegion", type text}, {"Region", type text}, {"Latitude", type number}, {"Longitude", type number}})
in
#"Changed Type";
接下来,导入你编写的模拟导航表查询,该查询可创建链接到这些数据集查询的固定表。 将其命名为 TripPinNavTable
:
TripPinNavTable = (url as text) as table =>
let
source = #table({"Name", "Data"}, {
{ "Airlines", GetAirlinesTable(url) },
{ "Airports", GetAirportsTable(url) }
})
in
source;
最后,将声明一个新的共享函数 TripPin.Contents
,其用作主数据源函数。 你还会从 TripPin.Feed
中删除 Publish
值,使其不再显示在“获取数据”对话框中。
[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);
注意
扩展可以将多个函数标记为 shared
,可以将或者不将它们与 DataSource.Kind
相关联。 但是,将函数与特定 DataSource.Kind
函数相关联时,每个函数必须具有名称和类型相同的必需参数集。 这是因为数据源函数参数会组合在一起,生成用于查找缓存凭据的“密钥”。
使用 TripPin.query.pq 文件完成所有更改并测试 TripPin.Contents
函数后,生成连接器。 可以继续使用以前创建的凭据,也可以设置一个新凭据,然后评估当前 Power Query 文件。
TripPin.Contents("https://services.odata.org/v4/TripPinService/")
创建导航表
使用便捷的 Table.ToNavigationTable 函数将静态表格式化为 Power Query 识别为导航表的内容。 由于此函数不是 Power Query 标准库的一部分,因此需要将其源代码复制到 .pq 文件中。
有了此帮助程序函数后,接下来更新 TripPinNavTable
函数即可添加导航表字段。
TripPinNavTable = (url as text) as table =>
let
source = #table({"Name", "Data", "ItemKind", "ItemName", "IsLeaf"}, {
{ "Airlines", GetAirlinesTable(url), "Table", "Table", true },
{ "Airports", GetAirportsTable(url), "Table", "Table", true }
}),
navTable = Table.ToNavigationTable(source, {"Name"}, "Name", "Data", "ItemKind", "ItemName", "IsLeaf")
in
navTable;
在再次生成连接器之后再次运行测试查询,会得到与上次类似的结果 — 添加了几列。
注意
看不到“导航器”窗口显示在 Visual Studio Code 的 PQTest 结果窗口中。 M 查询输出窗口始终显示基础表。
如果将扩展复制到 Power BI Desktop 自定义连接器并从“获取数据”对话框调用新函数,就会看到导航器出现。
如果右键选择导航树的根目录并选择“编辑”,就会看到与 Visual Studio 中相同的表。
结束语
在本教程中,你向扩展添加了导航表。 导航表是使连接器更易于使用的关键功能。 在本例中,导航表只有一个级别,但 Power Query UI 支持显示具有多个维度的导航表(即使这些表层次结构不规则)。