TMDL (表格式模型定義語言)
適用于:SQL Server 2016 和更新版本的 Analysis Services Azure Analysis Services Fabric/Power BI Premium
重要
表格式模型定義語言 (TMDL) 目前為預覽狀態。 預覽版時,功能和檔可能會變更。
表格式模型定義語言 (TMDL) 是相容性層級 1200 或更高版本表格式資料模型的物件模型定義語法。
TMDL 的主要元素包括:
- 與整個 表格式物件模型的完整相容性, (TOM) 。 每個 TMDL 物件都會公開與 TOM 相同的屬性。
- 以文字為基礎並針對人類互動和可讀性進行優化。 TMDL 使用類似 YAML 的文法語法。 每個 TMDL 物件都會以最少分隔符號的文字來表示,並使用縮排來標示父子式關聯性。
- 更好的編輯體驗,特別是具有來自不同內容類型內嵌運算式的屬性,例如資料分析運算式 (DAX) 和 M。
- 較適合共同作業,因為每個模型物件都有個別檔案標記法的資料夾標記法,因此更容易使用原始檔控制。
TMDL 的重要層面是使用空格縮排來表示 TOM 物件結構。 下列範例顯示使用 TMDL 時,表示表格式模型有多容易:
database Sales
compatibilityLevel: 1567
model Model
culture: en-US
table Sales
partition 'Sales-Partition' = m
mode: import
source =
let
Source = Sql.Database(Server, Database)
…
measure 'Sales Amount' = SUMX('Sales', 'Sales'[Quantity] * 'Sales'[Net Price])
formatString: $ #,##0
column 'Product Key'
dataType: int64
isHidden
sourceColumn: ProductKey
summarizeBy: None
column Quantity
dataType: int64
isHidden
sourceColumn: Quantity
summarizeBy: None
column 'Net Price'
dataType: int64
isHidden
sourceColumn: "Net Price"
summarizeBy: none
table Product
partition 'Product-Partition' = m
mode: import
source =
let
Source = Sql.Database(Server, Database),
…
column 'Product Key'
dataType: int64
isKey
sourceColumn: ProductKey
summarizeBy: none
relationship cdb6e6a9-c9d1-42b9-b9e0-484a1bc7e123
fromColumn: Sales.'Product Key'
toColumn: Product.'Product Key'
role Role_Store1
modelPermission: read
tablePermission Store = 'Store'[Store Code] IN {1,10,20,30}
expression Server = "localhost" meta [IsParameterQuery=true, Type="Text", IsParameterQueryRequired=true]
expression Database = "Contoso" meta [IsParameterQuery=true, Type="Text", IsParameterQueryRequired=true]
TMDL 資料夾結構
不同于 TMSL,TMDL 會使用資料夾結構。 預設資料夾結構只有一個 層級的子資料夾,全部都有 .tmdl 檔案:
- cultures
- 檢視方塊
- 角色
- 資料表
以及下列專案的 根檔案 :
- [資料庫]
- model
- 關聯性
- 運算式
- datasources
以下是 TMDL 資料夾的範例:
定義包括:
- 資料庫定義的一個檔案。
- 模型定義的一個檔案。
- 模型中 所有 資料來源的一個檔案。
- 模型中 所有 運算式的一個檔案。
- 模型中 所有 關聯性的一個檔案。
- 每個文化特性語言架構 都有 一個檔案。
- 每個檢視方塊 都有 一個檔案。
- 每個角色都有一個檔案。
- 每個資料表都有一個檔案。
- 資料表的所有內部中繼資料屬性 (資料行、階層、資料分割,...) 中繼資料都存在於父資料表 TMDL 檔案中。
TMDL API
類似于 表格式模型指令碼語言 (TMSL) ,有一個類別可處理 TMDL 序列化。 針對 TMDL,類別是Microsoft.AnalysisServices.Tabular命名空間下的TmdlSerializer。
TmdlSerializer 類別會公開方法來序列化和還原序列化 TMDL 檔:
資料夾序列化
public static void SerializeDatabaseToFolder (Database database, string path)
- 接收 TOM 資料庫物件和 TMDL 輸出路徑。
- 將 TOM 資料庫序列化為 TMDL 資料夾標記法。
深入瞭解 如何序列化至資料夾。
public static Database DeserializeDatabaseFromFolder (string path)
- 接收 TMDL 資料夾的完整路徑。
- 傳回 TMDL 資料夾的 TOM 資料庫物件表示。
深入瞭解 如何從資料夾還原序列化。
字串序列化
public static string SerializeObject (MetadataObject object, bool qualifyObject = true)
- 接收 TOM 物件並傳回其 TMDL 文字表示。
深入瞭解 如何將物件序列化為字串。
資料流程序列化
您可以將 TMDL 序列化/還原序列化至資料流程,以便將 TOM 物件轉換成位元組資料流程,以便跨平臺儲存、傳輸和互通性。 Stream API 也可讓您控制要載入哪些 TMDL 檔,以及輸出哪些 TMDL 檔。
TMDL 資料流程序列化是由 MetadataSerializationCoNtext 類別處理。
深入瞭解 如何使用資料流程來回序列化 TMDL。
TMDL 語言
物件宣告
除了 Server 物件之外,TMDL 會在Microsoft.AnalysisServices.Tabular 命名空間中公開整個 TOM資料庫物件樹狀結構。
TMDL 物件是藉由指定 TOM 物件類型,後面接著其名稱來宣告。 在下列程式碼範例中,每個物件類型: model
、 column
table
後面接著物件名稱。
model Model
culture: en-US
table Sales
measure Sales = SUM(…)
formatString: $ #,##0
column 'Customer Key'
datatype: int64
sourceColumn: CustomerKey
或 measure
之類的 partition
物件具有預設屬性,可在物件宣告的相同行或多行運算式的相同行 () = 分隔符號之後指派:
table Sales
partition Sales-Part1 = m
mode: import
...
measure Sales = SUM(…)
formatString: $ #,##0
measure 'Sales (ly)' =
var ly = ...
return ly
formatString: $ #,##0
如果 TMDL 物件名稱包含下列任何字元,則必須以單引號括住 (') :
- 點 (.)
- 等於 (=)
- 冒號 (:)
- 單引號 (')
- 空白字元 ( )
如果物件名稱包含單引號 (') ,請使用兩個單引號來逸出它。
物件屬性
物件屬性是在物件宣告或物件預設屬性多行運算式之後指定。 物件屬性值是在冒號 (之後指定 :) 分隔符號。 例如:
table Sales
lineageTag: e9374b9a-faee-4f9e-b2e7-d9aafb9d6a91
column Quantity
dataType: int64
isHidden
isAvailableInMdx: false
sourceColumn: Quantity
measure 'Sales Amount' =
var result = SUMX(...)
return result
formatString: $ #,##0
displayFolder: " My ""Amazing"" Measures"
下列規則適用于屬性值:
值必須位於冒號後面的同一行,而且不能有多個行。
Text 屬性值
- 前置和尾端雙引號是選擇性的,且會在序列化期間自動移除。
- 如果文字包含尾端或前置空白字元,則必須以雙引號括住 (「) 。
- 以雙引號括住時,如果值包含雙引號,請使用兩個雙引號來逸出兩個雙引號, (請參閱
displayFolder
上述程式碼範例中的 屬性) 。
您可以使用標準索引鍵/值組語法來設定布林值屬性,例如
'isAvailableInMdx'
上一個範例中的 屬性。 您也可以使用只宣告屬性名稱且true
隱含的快捷方式語法來設定它們。 例如,請參閱上一個範例中的 'isHidden' 屬性。
具名物件參考
某些物件屬性會保存其他模型物件的參考,例如:
- 階層層級中的資料行參考。
- 每個資料表資料行中的 sortByColumn 參考。
- 檢視方塊中的資料表/資料行/量值參考。
在 TMDL 中,會使用物件名稱進行參考,並遵循相同的逸出和單引號 (') 括住物件宣告的需求。 在下列程式碼範例中,您會看到保存另一個物件參考的物件屬性: column.sortByColumn
、 level.column
perspectiveMeasure.measure
和 perspectiveTable.table
。
table Product
column Category
sortByColumn: 'Category Order'
hierarchy 'Product Hierarchy'
level Category
column: Category
perspective Product
perspectiveTable Product
perspectiveMeasure '# Products'
如果需要參考完整名稱,TMDL 會使用 點 標記法來參考物件,例如: 'Table 1'.'Column 1'
子物件
TOM 物件樹狀結構包含許多位置及不同層級的子物件。 例如:
- 模型物件包含資料表、角色和運算式物件。
- 資料表物件包含資料行、量值和階層物件。
TMDL 不會明確宣告子集合。 相反地,其各自父系範圍內所有適用的子專案都會隱含地組成對應集合的元素。 例如,特定資料表範圍內的所有資料行元素都會成為 TOM 中該資料表之資料行集合的元素,如下所示:
table Sales
measure 'Sales Amount' = SUMX('Sales', [Quantity] * [Net Price])
measure 'Total Quantity' = SUM('Sales'[Quantity])
measure 'Sales Amount YTD' = TOTALYTD([Sales Amount], 'Calendar'[Date])
子物件不需要連續。 例如,您可以依任何順序和交錯來宣告資料行和量值。
預設屬性
某些物件類型具有預設屬性,大部分時間都會被視為 運算式。 預設屬性是特定物件類型。 如果適用,屬性值或運算式是在區段宣告之後 () = 分隔符號之後指定。
支援的語法:
- 值是在與區段標頭相同的行上指定。
- 值會指定為區段標頭後面的多行運算式。
在下列程式碼範例中,量值 Sales Amount
和資料分割 Sales-Partition1
是單行,量值 Quantity
是多行:
table Sales
measure 'Sales Amount' = SUM(...)
formatString: $ #,##0
measure Quantity =
var result = SUMX (...)
return result
formatString: #,##0
partition Sales-Partition1 = m
mode: import
source =
let
...
in
finalStep
運算式
有物件屬性是 TOM 中的文字屬性,在 TMDL 中取得特殊剖析。 整個文字會逐字讀取,因為它可以在 M 或 DAX 運算式中包含特殊字元,例如引號或方括弧。 運算式可以是多行或單行。 如果多行,它們必須緊接在屬性或物件宣告之後的行中。
TMDL 中的運算式值會指定為等於 () = 分隔符號,如下列範例所示:
table Table1
partition 'partition 1' = m
mode: import
source =
let
...
in
finalStep
measure Measure1 = SUM(...)
measure Measure2 =
var result = SUMX (
...
)
return result
formatString: $ #,##0
下列特殊規則適用于運算式:
- 多行運算式必須縮排到父物件屬性更深入的一層,而且整個運算式必須位於該縮排層級內。
- 所有外部縮排空白字元都會移除超過父物件的縮排層級。
- 允許在空白行 (空白行的垂直空白字元,) 且被視為運算式的一部分。
- 尾端空白行和空白字元會移除。
- 若要強制執行不同的縮排,或保留尾端空白行或空白字元,請使用三個反引號 () ``` 括住。
- 根據預設,如果運算式值包含任何可能會對往返 (造成修改的任何專案,TMDL 序列化程式將會以反引號括住,例如尾端空白字元、空白字元空白行) 。
以三個反引號括住的運算式 (```) 會逐字讀取,包括縮排、空白行和空白字元。 分隔符號應該緊接在等號之後 () = 和運算式後面的行,而且後面不能有任何專案,如下列範例所示:
table Table1
partition partition1 = m
mode: import
source = ```
let
...
in
finalStep
```
measure Measure1 = ```
var myVar = Today()
…
return result
```
使用三個反引號 (```) 分隔符號是選擇性的,只有在唯一的情況下才需要。 在大部分情況下,使用正確的縮排和物件宣告可確保正確剖析您新增至 屬性的任何運算式。
當運算式包含在反引號內時,會套用下列規則:
- 三個反引號之間的一切 (```) 都被視為多區塊運算式的一部分,而且不會套用 TMDL 縮排規則。 結束分隔符號會決定運算式內的縮排。
- 運算式內的相對縮排會保留。 結束分隔符號 () ``` 會決定運算式左界限, (請參閱上一個範例中的 'Measure1') 。
下列屬性會被視為運算式:
物件類型 | 屬性 | 運算式語言 |
---|---|---|
量值 | 運算式 | DAX |
MPartitionSource | 運算式 | M |
CalculatedPartitionSource | 運算式 | DAX |
QueryPartitionSource | 查詢 | NativeQuery |
CalculationItem | 運算式 | DAX |
BasicRefreshPolicy | SourceExpression、PollingExpression | M |
KPI | StatusExpression、TargetExpression、TrendExpression | DAX |
LinguisticMetadata | Content | XML 或 Json |
JsonExtendedProperty | 值 | Json |
FormatStringDefintion | 運算式 | DAX |
DataCoverageDefinition | 運算式 | DAX |
CalculationGroupExpression | 運算式 | DAX |
NamedExpression | 運算式 | DAX |
DetailRowsDefinition | 運算式 | DAX |
TablePermission | FilterExpression | DAX |
CalculatedColumn | 運算式 | DAX |
依物件類型的預設屬性
下表依物件類型顯示預設屬性和運算式語言:
物件型別 | Default 屬性 | 運算式語言 |
---|---|---|
量值 | 運算式 | DAX |
CalculatedColumn | 運算式 | DAX |
CalculationItem | 運算式 | DAX |
FormatStringDefinition | 運算式 | DAX |
DetailRowsDefinition | 運算式 | DAX |
CalculationExpression | 運算式 | DAX |
DataCoverageDefinition | 運算式 | DAX |
TablePermission | FilterExpression | DAX |
ColumnPermission | MetadataPermission | MetadataPermission 列舉 |
NamedExpression | 運算式 | M |
MPartitionSource | 運算式 | M |
CalculatedPartitionSource | 運算式 | DAX |
JsonExtendedProperty | 值 | Json |
Annotation | 值 | Text |
StringExtendedProperty | 值 | Text |
DataSource | 類型 | DataSourceType 列舉 |
分割區 | SourceType | PartitionSourceType 列舉 |
ChangedProperty | 屬性 | 屬性文字 |
ExternalModelRoleMember | MemberType | RoleMemberType 列舉 |
任何自訂 JSON 屬性 (例如 DataAccessOptions) | JSON 文件 | Json |
LinguisticMetadata | Content | Json |
說明
TMDL 提供描述的第一個類別支援。 針對模型檔用途,最佳做法是為每個 TOM 物件提供描述。 TMDL 會將描述視為具有明確語法支援的特殊屬性。 遵循許多其他語言的範例,使用三斜線 (///) 語法,在每個物件宣告之上指定描述。
描述區塊結尾與物件類型標記之間不允許空白字元。
描述可以分割成多行。 TMDL 序列化程式會將物件描述分成多行,以將發出的檔行保持在最大長度之下。 預設長度上限為 80 個字元。
/// Table Description
table Sales
/// This is the Measure Description
/// One more line
measure 'Sales Amount'' = SUM(...)
formatString: #,##0
部分宣告
TMDL 不會強制相同檔中的物件宣告。 不過,這類似于 C# 部分類別 ,其中可以在多個檔案之間分割物件定義。 例如,您可以在 [table].tmdl 檔案中宣告資料表定義,然後讓所有資料表的所有量值都定義在單一 [measures].tmdl 檔案中,如下所示:
table Sales
measure 'Sales Amount' = SUM(…)
formatString: $ #,##0
table Product
measure CountOfProduct = COUNTROWS(…)
為了避免剖析錯誤,無法宣告相同的屬性兩次。 例如,在兩個不同的 TMDL 檔中,針對相同資料表宣告兩個具有相同名稱的量值會導致錯誤。
物件參考
您可以使用 ref 關鍵字,後面接著物件類型和名稱來參考另一個 TMDL 物件。
例如,如果您使用字串序列化 API 序列化 Column 物件,結果會是:
ref table Table1
column Column1
datatype: int64
sourceColumn: Column1
決定性集合順序
ref關鍵字也可用來定義及保留 TOM <> TMDL 往返的集合順序。 在 TMDL 物件上避免原始檔控制差異特別重要,這些物件會序列化為個別檔案:資料表、角色、文化特性和檢視方塊。 ref關鍵字用於父物件 TMDL 檔案上,以宣告從 TOM 排序的專案:
model Model
ref table Calendar
ref table Sales
ref table Product
ref table Customer
ref table About
ref culture en-US
ref culture pt-PT
ref role 'Stores Cluster 1'
ref role 'Stores Cluster 2'
套用下列規則:
- 在 TMDL 還原序列化期間:
- 系統會忽略 TMDL 中參考但缺少 TMDL 檔案的物件。
- 未參考物件,但使用現有的 TMDL 檔案,會附加至集合結尾。
- 在 TMDL 序列化期間:
- TOM 中的所有集合物件都會使用 ref 關鍵字來參考。
- 只有一個專案的集合不會發出 ref。
- 如果相同的物件類型,則 ref 之間不會發出空白行。
屬性值分隔符號
只有兩個分隔符號/符號可以指派屬性值:
等於 (=)
冒號 (:)
- 用於每個非運算式 屬性值。 包含保存模型參考的屬性。
縮排
TMDL 會使用嚴格的空格縮排規則來表示 TOM 階層的結構。 TMDL 檔使用預設的單一 索引卷 標縮排規則。
每個物件可以有三個層級的縮排:
- 層級 1 - 物件宣告
- 層級 2 - 物件屬性
- 層級 3 - 物件屬性多行運算式
- 層級 2 - 物件屬性
在 TMDL 檔中,縮排會在下列情況下套用:
在物件區段標頭與物件的屬性之間 (資料表 - > 屬性) 。
table Sales isHidden lineageTag: 9a48bea0-e5fb-40fa-9e81-f61288e31a02
物件與其子物件之間 (資料表 - > 量值) 。
table Sales measure 'Sales Amount' = SUMX(...) measure 'Total Quantity' = SUM(...)
物件與其多行運算式之間 (資料表 - measure - >> expression) 。
table Sales measure 'Sales Amount' = var result = SUMX(...) return result formatString: $ #,##0
多行運算式必須縮排比物件屬性更深的一層,而且整個運算式必須位於該縮排層級內, (請參閱 運算式) 。
Model 的資料庫和直接子物件不需要縮排,因為它們會隱含地假設在根 Model 或 Database 底下:
- model
- 資料表
- 共用運算式
- 角色
- cultures
- 檢視方塊
- 關聯性
- 資料來源
- 查詢群組
- 模型層級注釋
- 模型層級擴充屬性
未遵循這些縮排規則會產生剖析錯誤。
空白
TMDL 預設會將下列規則套用至屬性和運算式值內的空白字元,如果未包含在反引號 ``` () 或雙引號 (「) :
- 在屬性值上,會修剪前置和尾端空白字元。
- 在運算式上,會卸載運算式結尾的空白字元。
- 空白字元行會修剪為空白行, (沒有空格/索引標籤) 。
大小寫
根據預設,序列化/寫入上的 TMDL API 會使用 camelCase,套用至:
- 物件類型
- 關鍵字
- 列舉值
在還原序列化/讀取時,TMDL API 不區分大小寫。
考量與限制
相關內容
現在您已瞭解 TMDL,請務必參閱 開始使用 TMDL ,瞭解如何取得及部署 Power BI 語意模型的 TMDL 模型標記法。
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應