top of page

What TMDL View Means for Model Versioning & Enterprise Workflows

  • Jihwan Kim
  • 2 days ago
  • 5 min read

In this writing, I’d like to share how I’ve been exploring TMDL (Tabular Model Definition Language) since it was in preview — and why its General Availability (GA) release changes how we should think about semantic model governance, versioning, and collaboration in Power BI and Fabric.


This isn’t just a new format; it’s a new way of working.



From PBIX to TMDL – Why This Is a Turning Point

For as long as I’ve worked with Power BI, the PBIX file has been the center of the modeling world. Everything — queries, relationships, measures, metadata — lived inside a single binary file. That simplicity helped Power BI grow quickly, but it also created a challenge: PBIX files were opaque. I couldn’t easily track who changed a measure, compare versions, or manage model promotion.


That’s why TMDL is such a big deal.


With TMDL View now generally available, Microsoft has officially moved the semantic model into an open, text-based, and version-controllable format.


The difference is immediate:

  • I can see and edit your model structure in text form.

  • I can track changes line by line in Git.

  • I can collaborate on model updates like software developers do with code.


What started as a modeling enhancement has now become a governance enabler.



What TMDL Actually Changes

At its core, TMDL (Tabular Model Definition Language) describes a semantic model in plain text — including tables, columns, relationships, roles, and DAX measures.

Here’s an example of what it looks like:


ree

createOrReplace

	table orders_fact_databricks
		lineageTag: 4358766d-678b-491e-9563-a605920bdfa7

		column ProductKey
			dataType: int64
			lineageTag: 56f7e740-7cdf-4b33-be64-374581befa06
			summarizeBy: none
			sourceColumn: ProductKey

			annotation SummarizationSetBy = Automatic

		column CustomerKey
			dataType: int64
			lineageTag: 93b7644e-762e-4662-873e-068ab583984f
			summarizeBy: none
			sourceColumn: CustomerKey

			annotation SummarizationSetBy = Automatic

		column OrderDocTypeKey
			dataType: int64
			lineageTag: 08f0854b-41c5-4d68-9975-c76886ece926
			summarizeBy: none
			sourceColumn: OrderDocTypeKey

			annotation SummarizationSetBy = Automatic

		column OrderStatusKey
			dataType: int64
			lineageTag: 17f15445-278b-4db3-aa01-9e52ac0b7f5f
			summarizeBy: none
			sourceColumn: OrderStatusKey

			annotation SummarizationSetBy = Automatic

		column ExchangeRateKey
			dataType: int64
			lineageTag: f5ac38ea-2fbb-41d0-bf23-b2e798bca58e
			summarizeBy: count
			sourceColumn: ExchangeRateKey

			annotation SummarizationSetBy = Automatic

		column OrderDate
			dataType: dateTime
			formatString: Long Date
			lineageTag: 6577e6e2-d7f0-4502-b131-19f46875a0f3
			summarizeBy: none
			sourceColumn: OrderDate

			annotation UnderlyingDateTimeDataType = Date

			annotation SummarizationSetBy = Automatic

		column BillingDate
			dataType: dateTime
			formatString: Long Date
			lineageTag: 6dba2eaf-70d9-461f-857a-d03f4d407485
			summarizeBy: none
			sourceColumn: BillingDate

			annotation UnderlyingDateTimeDataType = Date

			annotation SummarizationSetBy = Automatic

		column ShipDate
			dataType: dateTime
			formatString: Long Date
			lineageTag: 5724a9a6-7238-437c-a592-d3e0fdaee71b
			summarizeBy: none
			sourceColumn: ShipDate

			annotation UnderlyingDateTimeDataType = Date

			annotation SummarizationSetBy = Automatic

		column RequestGoodsReceiptDate
			dataType: dateTime
			formatString: Long Date
			lineageTag: 487ab6cc-09d0-4a15-afa8-d576f2f37167
			summarizeBy: none
			sourceColumn: RequestGoodsReceiptDate

			annotation UnderlyingDateTimeDataType = Date

			annotation SummarizationSetBy = Automatic

		column ConfirmGoodsReceiptDate
			dataType: dateTime
			formatString: Long Date
			lineageTag: 74b56cee-2c57-4b2f-a786-9d6ee0f9e79d
			summarizeBy: none
			sourceColumn: ConfirmGoodsReceiptDate

			annotation UnderlyingDateTimeDataType = Date

			annotation SummarizationSetBy = Automatic

		column NetOrderValue
			dataType: double
			lineageTag: 8e9c04fa-4363-4697-b46b-91d63b5f9a20
			summarizeBy: sum
			sourceColumn: NetOrderValue

			annotation SummarizationSetBy = Automatic

			annotation PBI_FormatHint = {"isGeneralNumber":true}

		column NetOrderQuality
			dataType: int64
			lineageTag: 9bf8af6b-9a9f-454d-9d6f-d876d8fffe9d
			summarizeBy: sum
			sourceColumn: NetOrderQuality

			annotation SummarizationSetBy = Automatic

		column LocalExchangeRate
			dataType: double
			lineageTag: 3926de22-691d-4943-8296-ed9206e9d78a
			summarizeBy: sum
			sourceColumn: LocalExchangeRate

			annotation SummarizationSetBy = Automatic

			annotation PBI_FormatHint = {"isGeneralNumber":true}

		partition orders_fact_databricks = m
			mode: import
			source =
					let
					    Source = DatabricksMultiCloud.Catalogs("dbc-3f1cd0d5-6766.cloud.databricks.com", "/sql/1.0/warehouses/304212cca4862ea4", null),
					    Database = Source{[Name="spacepartscodw",Kind="Database"]}[Data],
					    Schema = Database{[Name="fact",Kind="Schema"]}[Data],
					    Data = Schema{[Name="orders",Kind="Table"]}[Data]
					in
					    Data

What’s powerful is not the syntax, but what it enables: version control, diffing, and review.

When a developer edits a measure in the Power BI Service or Desktop, that change is represented as a text update in Git. I can compare versions, review deltas, and merge branches safely.

This closes one of the biggest historical gaps in Power BI — change traceability.




TMDL and Governance: Model-as-Code

Once I started to learn TMDL, I started viewing the semantic model not as a “dataset” but as code.

That mindset changes governance practices:

  • Change tracking: Every measure edit becomes a commit in Git, visible to reviewers.

  • Pull requests: Model updates can be reviewed by peers before merging.

  • Auditability: All structural changes are transparent and timestamped.

  • Rollback: You can revert models to any previous version if something breaks.

It also means I can enforce modeling standards just like code standards — naming conventions, measure formatting, and performance validation can all be reviewed before deployment.


This “model-as-code” approach finally gives BI teams the same level of governance developers have enjoyed for years.




Enterprise Versioning Strategy with TMDL

In an enterprise context, the biggest win is version alignment across environments — Dev, Test, and Prod.

Here’s a model lifecycle pattern that’s working well:

  1. Develop in Dev: Modelers edit the model either in Power BI Desktop or directly in the Service.

  2. Commit to Git: The workspace is connected to Git, so TMDL updates automatically sync.

  3. Pull Request Review: Team members review DAX or schema changes using diff tools.

ree

  1. Promote via Deployment Pipelines: The validated model is promoted upward — the same TMDL files move through Test and Prod.

    Overview of Fabric deployment pipelines - Microsoft Fabric | Microsoft Learn


ree


This creates full traceability between development, approval, and release.

A small but important lesson I’ve learned: always make Git the source of truth. Even if edits are made in the Service, sync them back immediately. Otherwise, environment drift can occur where Git and Production no longer match.



Coexistence with PBIX and Migration Strategy

Most organizations won’t drop PBIX overnight — nor should they.

TMDL is part of an evolution. I can take a gradual approach:

  • Keep using PBIX for Desktop development where needed.

  • Connect workspaces to Git to export models in TMDL automatically.

  • Use TMDL as my review and governance layer, even if PBIX remains my authoring tool.

This hybrid approach lets me enjoy version control and auditing benefits while keeping existing workflows stable. Over time, as my team adopts more Service-based modeling, TMDL will naturally become the backbone of my semantic model management.




Lessons Learned Along the Way

Through testing TMDL in production-like environments, a few insights stood out:

  • Git commits are frequent 

  • Developer onboarding matters — not everyone is comfortable reading TMDL; short internal workshops help.

  • Desktop vs Service edits — always decide my “primary edit location” to avoid conflicts.

  • Review discipline — automated validation or lightweight DAX diff tools make review faster and safer.

  • Cultural change — governance works best when the BI team embraces code review habits.

TMDL brings transparency, and good process keeps it sustainable.



TMDL View represents more than a new format. It’s the foundation of model lifecycle governance in Power BI and Fabric.


For enterprises, the implications are significant:

  • Models become text-based, reviewable, and versioned.

  • Git and pipelines can now handle BI artifacts alongside data engineering code.

  • Governance, auditing, and compliance become measurable.



In short, TMDL brings BI closer to DevOps — something that’s been missing for years.




I hope this helps having fun in exploring TMDL in your own Fabric environment, and perhaps start rethinking how the team manages semantic model versioning at scale.

Comments


bottom of page