M语言(Power Query公式语言)中“开放式记录类型”的目的和用途

3
我已经阅读了Power Query的"M"语言规范,其中提到了开放式记录类型。我的理解是开放类型允许添加其他字段,但我对此还没有具体的了解。
声明普通(闭合)记录的方式很简单。
myRecord = [name = "MyName", Age = 30]

从语言规范(5.4:记录类型)中:

myRecordType1 = type [Name = text, Age = number]       // Closed Record _type_
myRecordType2 = type [Name = text, Age = number, ...]  // Open Record _type_

然而,

myRecord = [Name = "MyName", Age = 30, ...] // Not valid code

所以,这个概念似乎只涉及自定义记录类型,而不是一般的记录,但我不知道该怎么做。我尝试了这个:
testFunc = (inputArg as myRecordType2) => 1 // Not valid code

希望函数只接受具有“名称”和“年龄”字段以及可选其他字段的记录,但实际并非如此。尝试使用“as”关键字可能不起作用,但即使这样也不行。
testTable = Table.AddColumn(Table.FromRecords({[A=1]}), "newcol", each [Name="MyName", Age=30], type myRecordType1) // Not valid code

有人能举例说明这个用例吗?我在语言规范中漏掉了什么吗?


下面的回答确实有助于更好地理解它,但我仍然不知道这在哪里会有用。有任何想法/用例吗? - alazyworkaholic
2个回答

3

我的理解如下。欢迎任何评论(包括其他想法)。

类型是值的分类。有两种类型:原始类型(数字、文本等)和自定义类型,例如特定的表类型或记录类型。

例如,表类型是列名称、类型和任何键值的集合。 可以首先指定表类型,然后在创建表时使用:

Tabeltype = type table[Key = number, Value = text],
TabletypeWithKey =  Type.AddTableKey(Tabeltype,{"Key"},true), 
TableWithKey = #table(TabletypeWithKey, {{1, "A"},{2, "B"}, {3, "C"}})
同样地,您可以创建记录类型。
但是,在创建记录时,您不能直接使用记录类型。 您可以使用Value.ReplaceType将类型“归属”于值,例如将记录类型归属于记录,前提是记录类型已关闭且没有可选字段。 以下代码示例。
我希望有可能验证值是否与特定类型匹配,但是这只能用于基本类型(使用关键字“is”或“as”或“Type.Is”)。
因此,根据我的解释,我创建了下面的代码来检查记录是否符合记录类型的规范:我无法保证它是完全正确的。 目前它是一个查询,所以您可以看到发生了什么,但是您可以轻松将其转换为函数,并在当前已注释的代码底部使用示例。
// Mext 2 lines to be decommented to turn the code into a function
//let
//    fnCheckConformity = (Record1 as record, RecordType as type) as logical =>
let
    // Next 2 lines to be removed when turning this code into a function
    Record1 = [x = 1, A = 3, B = 4],
    RecordType = type [x = number, optional y = text,...],
    RecordTypeFields = Type.RecordFields(RecordType),
    ToTable = Record.ToTable(RecordTypeFields),
    RecordTypeTable = Table.ExpandRecordColumn(ToTable, "Value", {"Optional", "Type"}, {"Optional", "Type"}),
    RecordTable = Table.FromColumns({Record.FieldNames(Record1),Record.FieldValues(Record1)},{"Record FieldName", "Record FieldValue"}),
    JoinedTable = Table.Join(RecordTypeTable, "Name", RecordTable, "Record FieldName", JoinKind.FullOuter),
    ConformityCheck = Table.AddColumn(JoinedTable, "Conform", 
                        each if [Optional] = null then Type.IsOpenRecord(RecordType) else
                             if [Optional] then true else
                             if [Record FieldValue] <> null then Value.Is([Record FieldValue], [Type]) else
                             false),
    Result = List.AllTrue(ConformityCheck[Conform])
in
    Result
// Add a comma after Result when turning the code above into a function
/* The code below can be used when turning the code above into a function.
// Examples:
    OpenRecordType = type [x = number, optional y = text,...],
    ClosedRecordType = type [x = number, y = text],
    RecordA = [x = 1],
    RecordB = [x = 1, A = 3, B = 4],
    RecordC = [x = 1, y = "MarcelBeug"],
//  RecordC is ascribed type ClosedRecordType:
    RecordCTyped = Value.ReplaceType(RecordC, ClosedRecordType),
    Conformity1 = fnCheckConformity(RecordA, OpenRecordType),   // true
    Conformity2 = fnCheckConformity(RecordA, ClosedRecordType), // false
    Conformity3 = fnCheckConformity(RecordB, OpenRecordType),   // true
    Conformity4 = fnCheckConformity(RecordB, ClosedRecordType), // false
    Conformity5 = fnCheckConformity(RecordC, OpenRecordType)    // true
in
    Conformity5 */

1

Marcel的回答很好,但我可以增加一些背景信息。

的确,在"M"中今天并没有太多使用开放记录类型的用途。

其中一个可能有用的地方是,如果我们有“不规则”表的概念,例如这个CSV文件在不同行中有两个、三个和四个数据字段。

A,B,C
1,2
1,2,3
1,2,3,4

Loading this CSV into PQ editor / Excel / PowerBI Desktop / powerbi.com will probably work, but it's not a good fit for a table value. In the "M" design today, a table is basically a list of closed records with non-optional fields (so you can't have a table row with more or less fields than the table columns).
一些其他的数据源,如Azure表或OData也可能使用不规则表格。目前,我们将返回一个具有一些固定列和一个记录列 [Content] 或 [Open Types] 的表。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接