TMDL 入门
适用于:SQL Server 2016 及更高版本的 Analysis Services Azure Analysis Services Fabric/Power BI Premium
重要
表格模型定义语言 (TMDL) 目前为预览版。 在预览版期间,功能和文档可能会更改。
在开始本文之前,请务必全面了解 表格模型定义语言 (TMDL) 概述中所述的概念。
浏览 TMDL 的最简单方法是 (AMO) Nuget 包 引用 Analysis Services 管理对象,并使用 TMDL API 方法对 TMDL 进行序列化和反序列化。
获取 TMDL 模型表示形式
下面的代码示例演示如何在Power BI Premium工作区中获取语义模型的 TMDL 模型表示形式:
var workspaceXmla = " <Workspace XMLA address>";
var datasetName = "<dataset name>";
var outputPath = System.Environment.CurrentDirectory;
using (var server = new Server())
{
server.Connect(workspaceXmla);
var database = server.Databases.GetByName(datasetName);
var destinationFolder = $"{outputPath}\\{database.Name}-tmdl";
TmdlSerializer.SerializeDatabaseToFolder(database.Model, destinationFolder);
}
输出是一个文件夹,其中包含模型的 TMDL 表示形式,如下所示:
序列化到文件夹后,使用文本编辑器编辑 TMDL 文件。 例如,通过使用 Visual Studio Code我们可以添加新度量值[Sales Amount (Computers) ]:
/// Sales data for year over year analysis
table Sales
partition 'Sales-Part1' = m
mode: Import
source =
let
…
in
#"Filtered Rows1"
measure 'Sales Amount' = SUMX('Sales', [Quantity] * [Net Price])
formatString: $ #,##0
measure 'Sales Amount (Computers)' = CALCULATE([Sales Amount], 'Product'[Category] = "Computers")
formatString: $ #,##0
为了获得更好的体验,可以安装 Visual Studio Code TMDL 语言扩展。
部署 TMDL 模型表示形式
下面的代码示例演示如何将模型的 TMDL 模型表示形式部署到Power BI Premium工作区:
var xmlaServer = "<Workspace XMLA address>";
var tmdlFolderPath = $"{System.Environment.CurrentDirectory}\\Contoso-tmdl";
var model = TmdlSerializer.DeserializeDatabaseFromFolder(tmdlFolderPath);
using (var server = new Server())
{
server.Connect(xmlaServer);
using (var remoteDatabase = server.Databases[model.Database.ID])
{
model.CopyTo(remoteDatabase.Model);
remoteDatabase.Model.SaveChanges();
}
}
执行时,新度量值将部署到模型。
处理 TMDL 序列化错误
在 TMDL 序列化方法中检测到错误时,除了引发一些常见的 .NET 异常(如 ArgumentException
和 InvalidOperationException
),还会返回特定于 TMDL 的异常。
TmdlFormatException
如果 TMDL 文本不是有效的语法,则引发 。 例如,无效关键字 (keyword) 或缩进。TmdlSerializationException
如果 TMDL 文本有效,但违反了 TOM 元数据逻辑,则会引发 。 例如,值的类型与预期类型不匹配。
除了异常详细信息外,还包括以下内容:
document path
:包含错误的 TMDL 文件的路径。line number
:包含错误的行号。line text
:包含错误的行文本。
处理 TmdlFormatException
的代码示例:
try
{
var tmdlPath = "<TMDL Folder Path>";
var model = TmdlSerializer.DeserializeDatabaseFromFolder(tmdlPath);
}
catch (TmdlFormatException ex)
{
Console.WriteLine($"Error on Deserializing TMDL '{ex.Message}', document path: '{ex.Document}' line number: '{ex.Line}', line text: '{ex.LineText}'");
throw;
}
对象文本序列化
下面的代码示例演示如何将列序列化为 TMDL:
var output = TmdlSerializer.SerializeObject(model.Tables["Product"].Columns["ProductKey"], qualifyObject: true);
Console.WriteLine(output);
输出:
ref table Product
column ProductKey
dataType: int64
isKey
formatString: 0
isAvailableInMdx: false
lineageTag: 4184d53e-cd2d-4cbe-b8cb-04c72a750bc4
summarizeBy: none
sourceColumn: ProductKey
annotation SummarizationSetBy = Automatic
流序列化
下面的代码示例演示如何将语义模型序列化为单个文本变量:
var output = new StringBuilder();
foreach (MetadataDocument document in model.ToTmdl())
{
using (TextWriter writer = new StringWriter(output))
{
document.WriteTo(writer);
}
}
Console.WriteLine(output.ToString());
下面的代码示例演示如何从 TMDL 反序列化,不包括角色:
var context = MetadataSerializationContext.Create(MetadataSerializationStyle.Tmdl);
var files = Directory.GetFiles("[TMDL Directory Path]", "*.tmdl", SearchOption.AllDirectories);
foreach (var file in files)
{
if (file.Contains("/roles/"))
continue;
using (TextReader reader = File.OpenText(file))
{
context.ReadFromDocument(file, reader);
}
}
var model = context.ToModel();
反馈
https://aka.ms/ContentUserFeedback。
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈