mcpField
T
tmdl-mastery

tmdl-mastery

github.com/josiahsiegel数据与数据库5992 次安装19 周前更新
代码仓库

关于 tmdl-mastery

面向 Power BI 和 Analysis Services 语义模型开发者的 TMDL 语法与工作流参考技能,涵盖文件结构、序列化、验证和部署。

主要功能

  1. 01TMDL 语法与对象声明参考
  2. 02文件夹结构与表达式说明
  3. 03.NET 序列化 API 示例
  4. 04语法及元数据验证流程
  5. 05Power BI Desktop TMDL 视图说明

适用场景

  1. 01将语义模型纳入源代码管理
  2. 02通过 TMDL 脚本修改模型
  3. 03使用 .NET 序列化或反序列化模型

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/josiahsiegel/claude-plugin-marketplace --skill tmdl-mastery

安装后在 Claude Code 中输入/tmdl-mastery确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
tmdl-cicd-patterns.md
tmdl-examples-cookbook.md
tmdl-programmatic-python.md
tmdl-syntax-reference.md

详细介绍

TMDL(表格模型定义语言)精通

概述

TMDL 参考内容涵盖语言语法、文件夹结构、对象类型、表达式、序列化 API、CI/CD 和部署。TMDL 是一种人类可读且便于进行源代码管理的格式,适用于兼容级别为 1200 及以上的 Power BI 和 Analysis Services 语义模型。

2026 年状态概览

方面状态(截至 2026 年 4 月)
TMDL 语言 GA自 2024 年 8 月起正式发布(GA)——不再是预览版
Power BI Desktop 中的 TMDL 视图正式发布(GA)——支持语义突出显示、自动补全、代码操作、差异预览和兼容性提示
TMDL 作为默认 PBIP 语义模型格式默认格式——model.bim 是旧版 BIM 格式;新建 PBIP 项目会写入 definition/*.tmdl 文件
Fabric Git 集成将语义模型导出为 TMDL(而非 TMSL/BIM)
TMSL / BIM未弃用——仍支持 XMLA 脚本命令,以及需要 JSON 的工具。源代码管理使用 TMDL,XMLA createOrReplace 命令脚本使用 TMSL
兼容级别推荐使用 1550+;某些较新的属性(例如 formatStringDefinition、计算组多选/空选表达式)要求 1601+
Tabular Editor 2(免费)支持 TMDL 读写(2.17+)
Tabular Editor 3(付费)提供完整的 TMDL IDE,包含 DAX 调试器和关系图视图
VS Code TMDL 扩展Microsoft 的 analysis-services.TMDL 和社区扩展 CPIM.TMDL-language-support(支持 DAX + M 突出显示、代码操作、格式化和面包屑导航)
Report Server不支持 TMDL——继续使用旧版 PBIX 二进制格式

要点: 对于纳入源代码管理的新 Power BI / Fabric 语义模型,请使用 TMDL。对于 XMLA 脚本或需要 model.bim 的工具,请保留 TMSL。

TMDL 与 TMSL 和 BIM 的对比

方面TMDL(.tmdl 文件夹)TMSL / BIM(model.bim)
格式类 YAML 文本,基于缩进单个 JSON 文件
文件每个表、角色、区域性和透视图各一个文件单体文件
Git 友好性极佳——差异粒度细,合并冲突少较差——整个模型都在一个差异中
可读性高——分隔符少,内嵌 DAX/M低——JSON 字符串需要转义
工具支持VS Code 扩展、Desktop 中的 TMDL 视图、Tabular Editor 3任意 JSON 编辑器、Tabular Editor 2/3
APITmdlSerializer(.NET)JsonSerializer(.NET)、TMSL 命令
迁移可通过 Tabular Editor 或 Desktop 从 BIM 转换默认旧版格式

何时使用 TMDL: 任何新的、纳入源代码管理的 CI/CD 或团队 PBIP 项目。

何时使用 TMSL/BIM: 旧版项目、Report Server(不支持 TMDL)或仅接受 BIM 的工具。

对象声明语法

声明对象时,先指定 TOM 对象类型,再指定其名称:

model Model
    culture: en-US

table Sales

    measure 'Sales Amount' = SUM(Sales[Amount])
        formatString: $ #,##0

    column 'Product Key'
        dataType: int64
        sourceColumn: ProductKey
        summarizeBy: none

主要规则:

  • 如果名称包含点、等号、冒号、单引号或空白字符,请用单引号括起
  • 名称中的单引号需通过重复书写进行转义:'My ''Special'' Table'
  • 子对象通过缩进隐式嵌套在其父对象下(无需显式集合)
  • 子对象不必连续排列——列和度量值可以自由交错

属性语法

属性使用冒号作为分隔符;表达式使用等号作为分隔符:

column Category
    dataType: string          /// colon for non-expression properties
    sortByColumn: 'Cat Order' /// colon for object references
    isHidden                  /// boolean shortcut (true implied)
    isAvailableInMdx: false   /// explicit boolean

measure Total = SUM(Sales[Amount])   /// equals for default expression
    formatString: $ #,##0            /// colon for properties after expression

文本属性值: 开头和结尾的双引号可省略,也会自动去除。如果值开头或结尾包含空白字符,则必须使用双引号。内部双引号需通过重复书写进行转义。

按对象类型划分的默认属性

对象类型默认属性语言
measureExpressionDAX
calculatedColumnExpressionDAX
calculationItemExpressionDAX
partition (M)ExpressionM
partition (calculated)ExpressionDAX
tablePermissionFilterExpressionDAX
namedExpressionExpressionM
annotationValueText
jsonExtendedPropertyValueJSON

默认属性使用等号(=),可以写在同一行,也可以作为多行表达式写在后续行中。

表达式——单行和多行

/// Single-line expression
measure 'Sales Amount' = SUM(Sales[Amount])

/// Multi-line expression (indented one level deeper than parent properties)
measure 'YoY Growth %' =
        VAR CurrentSales = [Sales Amount]
        VAR PYSales = CALCULATE([Sales Amount], SAMEPERIODLASTYEAR('Date'[Date]))
        RETURN DIVIDE(CurrentSales - PYSales, PYSales)
    formatString: 0.00%

/// Triple-backtick block for verbatim content (preserves whitespace exactly)
partition 'Sales-Part' = m
    mode: import
    source = ```
        let
            Source = Sql.Database("server", "db"),
            Sales = Source{[Schema="dbo",Item="Sales"]}[Data]
        in
            Sales
        ```

表达式规则:

  • 多行表达式的缩进比父属性多一级
  • 除非使用三反引号代码块,否则会删除行尾空格
  • 三反引号代码块会保留空白;结束定界符决定左边界

描述(/// 语法)

/// This table contains all sales transactions
/// Updated daily via incremental refresh
table Sales

    /// Total revenue across all product lines
    measure 'Sales Amount' = SUM(Sales[Amount])

对象上方的三斜杠注释会成为其 TOM Description 属性。描述块与对象类型关键字之间不能有空白。

Ref 关键字

引用另一个 TMDL 对象或定义集合排序:

/// In model.tmdl -- defines table ordering for deterministic roundtrips
model Model
    culture: en-US

ref table Calendar
ref table Sales
ref table Product
ref table Customer

ref culture en-US
ref culture pt-PT

ref role 'Regional Manager'

规则: 反序列化时,会忽略已引用但缺少对应文件的对象。有文件但没有 ref 的对象会追加到集合末尾。

TMDL 文件夹结构

definition/
  database.tmdl           # Database properties (compatibilityLevel, etc.)
  model.tmdl              # Model properties, ref declarations
  relationships.tmdl      # All relationships
  expressions.tmdl        # Shared/named expressions (Power Query parameters)
  functions.tmdl          # DAX user-defined functions
  dataSources.tmdl        # Legacy data sources
  tables/
    Sales.tmdl            # Table + all its columns, measures, partitions, hierarchies
    Product.tmdl
    Calendar.tmdl
  roles/
    RegionalManager.tmdl  # Role definition with permissions and members
    Admin.tmdl
  cultures/
    en-US.tmdl            # Translations for all objects in this culture
    pt-PT.tmdl
  perspectives/
    SalesView.tmdl        # Perspective definition

每个表、角色、区域性设置和透视各使用一个文件。所有内部元数据(列、度量值、分区、层次结构)都位于父表文件中。

TMDL 脚本(createOrReplace)

使用 Power BI Desktop 中的 TMDL 视图,将更改应用于实时语义模型:

createOrReplace

    table 'Time Intelligence'
        calculationGroup
            precedence: 1

        calculationItem Current = SELECTEDMEASURE()

        calculationItem YTD =
                CALCULATE(SELECTEDMEASURE(), DATESYTD('Calendar'[Date]))

        calculationItem PY =
                CALCULATE(SELECTEDMEASURE(), SAMEPERIODLASTYEAR('Calendar'[Date]))

        column 'Time Calc'
            dataType: string
            sourceColumn: Name
            sortByColumn: Ordinal

        column Ordinal
            dataType: int64
            sourceColumn: Ordinal
            summarizeBy: none

每次脚本执行只能使用一个命令动词。createOrReplace 命令会创建或替换指定对象及其所有后代对象。

缩进规则

TMDL 使用严格的空白缩进,默认每级缩进一个 制表符:

  • 第 1 级: 对象声明(table、measure、column)
  • 第 2 级: 对象属性(dataType、formatString)
  • 第 3 级: 多行表达式(DAX/M 代码)

数据库级和模型级的直接子级(table、relationship、role、culture、perspective、expression)无需缩进,因为它们隐含地位于根级之下。缩进不正确会导致 TmdlFormatException。

大小写和空白

  • 序列化对对象类型、关键字和枚举值使用 camelCase
  • 反序列化时 不区分大小写
  • 属性值开头和结尾的空白会被去除
  • 表达式末尾的空行会被删除
  • 表达式中的纯空白行会保留为空行

TMDL 序列化 API(.NET)

using Microsoft.AnalysisServices.Tabular;

// Serialize model to TMDL folder
TmdlSerializer.SerializeDatabaseToFolder(database, @"C:\output\model-tmdl");

// Deserialize TMDL folder back to TOM
var db = TmdlSerializer.DeserializeDatabaseFromFolder(@"C:\output\model-tmdl");

// Serialize single object to string
string tmdl = TmdlSerializer.SerializeObject(table.Measures["Total Sales"]);

NuGet 包: Microsoft.AnalysisServices.NetCore.retail.amd64(或对应的 .NET Framework 版本)

错误类型: TmdlFormatException(语法无效)和 TmdlSerializationException(语法有效,但 TOM 元数据无效)。两者都包含 Document、Line 和 LineText 属性。

自我验证

部署生成的任何 TMDL 之前,请运行 powerbi-master:validation-testing 技能提供的四层验证流程:

  1. 语法——TmdlSerializer.DeserializeDatabaseFromFolder 会捕获 TmdlFormatException(缩进错误、关键字无效)
  2. 元数据——同一调用会捕获 TmdlSerializationException(属性组合无效),而 model.Validate() 会捕获悬空引用
  3. 最佳实践——Tabular Editor 2 CLI 的 -A 开关或 semantic-link-labs.run_model_bpa 会运行标准 Microsoft BPA 规则集
  4. 血缘关系——model.Validate().Errors 加上自定义 Tabular Editor C# 脚本,可捕获 sortByColumn / 度量值引用列的问题

validation-testing 技能为每一层提供可直接运行的示例(C#、Python、GitHub Actions YAML)。推荐部署前务必进行验证。

Power BI Desktop 中的 TMDL 视图(2026)

TMDL 视图是 Power BI Desktop 中集成的代码编辑器,用于通过脚本编写语义模型更改。截至 2026 年发布周期,其功能包括:

  • 语义高亮、自动补全(Ctrl+Space)、悬停提示和代码操作(生成沿袭标记、纠正属性拼写错误)
  • 代码格式化,可通过 Shift+Alt+F 或功能区中的“格式”按钮进行(包括通过上下文菜单使用“格式化所选内容”)
  • 错误诊断,并提供专用的“问题”窗格
  • 预览差异 —— 并排或内联显示执行脚本前后的模型 TMDL 差异,可通过工具栏导航(预览运行仅支持有效的 TMDL)
  • 兼容性级别升级提示 —— 如果脚本使用的属性高于当前模型兼容性级别(例如,为 formatStringDefinition 从 1550 升级到 1601),Desktop 会提示自动升级
  • 多标签页脚本,保存在 PBIP 项目的 TMDLScripts/ 文件夹中(每个标签页对应一个文件)
  • 将对象从“数据”窗格拖到编辑器中,即可将其编写为 createOrReplace;拖动前按住 Ctrl 可多选
  • 右键单击 > 编写 TMDL 脚本,可将脚本发送到新标签页或剪贴板
  • 应用按钮可应用仅元数据更改(不刷新数据);通过 TMDL 重命名列会使其与 sourceColumn 脱离关联(Power Query 编辑器仍显示源名称)
  • 通过正则表达式查找和替换批量重命名 —— 常见用途包括移除前缀(fact_、dim_)或更改大小写

限制: Desktop 不会热重载从外部更改的 TMDL 文件。在 VS Code 中编辑 .tmdl 文件后,请重启 Power BI Desktop 以加载更改。

Semantic Link Labs(Fabric 笔记本中的 Python TOM)

若要在没有 .NET 工具链的情况下通过 Python 编写语义模型脚本,请在 Fabric 笔记本中使用 semantic-link-labs(PyPI:semantic-link-labs)。它提供了 TOM 的 Python 风格封装:

%pip install semantic-link-labs -q

import sempy_labs as labs
from sempy_labs.tom import connect_semantic_model

with connect_semantic_model(dataset="SalesModel", workspace="Sales-Dev", readonly=False) as tom:
    # Add a measure
    tom.add_measure(
        table_name="Sales",
        measure_name="Sales Amount",
        expression="SUM(Sales[Amount])",
        format_string="$ #,##0.00",
        display_folder="Revenue",
    )

    # Add an incremental refresh policy
    tom.add_incremental_refresh_policy(
        table_name="Sales",
        column_name="OrderDate",
        start_date="2020-01-01T00:00:00",
        end_date="2025-12-31T00:00:00",
        incremental_granularity="Day",
        incremental_periods=30,
        rolling_window_granularity="Month",
        rolling_window_periods=36,
    )

    # tom.save_changes() is called automatically on context exit

完整操作指南请参阅 references/tmdl-programmatic-python.md。

其他资源

参考文件
  • references/tmdl-syntax-reference.md —— 完整的 TMDL 语法和语法规则参考,涵盖所有对象类型、属性和表达式规则
  • references/tmdl-examples-cookbook.md —— 每种对象类型的可复制粘贴 TMDL 示例:表、列、度量值、分区、关系、角色、透视、区域性、计算组、层次结构、KPI、注释和字段参数
  • references/tmdl-cicd-patterns.md —— CI/CD 管道、Git 集成、部署模式、Tabular Editor CLI、Azure DevOps 和 GitHub Actions 工作流,以及合并冲突策略
  • references/tmdl-programmatic-python.md —— 在 Fabric Python 笔记本中使用 semantic-link-labs / SemPy 编写 TOM 脚本:度量值、计算组、增量刷新、RLS、Direct Lake、BPA 和模型导出模式
相关技能
  • powerbi-master:validation-testing —— 在部署前验证 TMDL 构件:TmdlSerializer 解析器、TOM Validate、通过 Tabular Editor CLI / semantic-link-labs 使用 BPA、自定义 C# 规则脚本
Microsoft Learn 官方参考(2026)

评论

支持 Markdown