TMDL — Tu modelo semántico como código
Imagina poder guardar todo tu modelo de Power BI como archivos de texto legibles, versionarlos en Git y revisarlos como si fueran código. Eso es exactamente lo que hace TMDL: convierte tu modelo en algo que puedes leer, editar, comparar y colaborar como cualquier otro proyecto de software.
¿Qué es TMDL?
TMDL son las siglas de Tabular Model Definition Language, un lenguaje creado por Microsoft para representar modelos semánticos tabulares como archivos de texto legibles por humanos.
Piensa en tu modelo de Power BI como en una receta de cocina. Durante años, esa receta vivía encerrada en un .pbix, que es básicamente una caja negra binaria: si la abres con un editor de texto ves ruido incomprensible. No puedes saber qué cambió entre ayer y hoy, no puedes compararlo con la versión de tu compañero, y si dos personas intentan editarlo a la vez... desastre total 🍝
TMDL convierte esa receta en tarjetas individuales bien ordenadas: una para cada tabla, una para cada medida, una para las relaciones. Cada tarjeta es un archivo de texto limpio que puedes abrir, editar, enviar a revisión y guardar en Git como cualquier otro código.
Legible por humanos
Sintaxis clara e indentada. Cualquier persona con algo de contexto puede leer una medida o entender una relación sin herramientas especiales.
Modular
Cada objeto del modelo tiene su propio archivo. Las tablas, medidas, columnas y relaciones viven separadas y son fáciles de localizar.
Versionable
Al ser texto plano, Git puede comparar cambios línea a línea. Sabrás exactamente qué medida cambió, cuándo y quién lo hizo.
Colaborativo
Varios desarrolladores pueden trabajar en paralelo sobre tablas distintas sin pisarse. Los merges son resolubles como en cualquier proyecto de código.
Automatizable
Perfecto para pipelines de CI/CD: puedes generar, validar y desplegar modelos de forma automatizada sin abrir el Desktop.
Auditable
El historial de Git te da trazabilidad total. ¿Quién borró esa medida de margen? ¿Cuándo se cambió la fórmula? Todo queda registrado.
El problema con el .pbix
Para entender por qué TMDL existe, hay que entender primero por qué el .pbix se quedó corto cuando los proyectos crecen.
El formato .pbix es un archivo ZIP que contiene el modelo, los datos (si están importados), el informe y los metadatos, todo comprimido y codificado en binario. Esto está genial para compartir un archivo "todo en uno", pero es un problema serio en equipos de trabajo:
😩 Trabajando con .pbix
- Binario: Git solo puede decirte que el archivo cambió, no qué cambió dentro
- Un solo archivo para todo: datos, informe y modelo mezclados
- Colaboración imposible en paralelo — el último en guardar machaca al anterior
- No puedes hacer code review de las medidas
- Difícil de integrar en pipelines automatizados
- Si se corrompe el archivo, pierdes todo
🌸 Trabajando con TMDL (.pbip)
- Texto plano: cada cambio en cada línea es visible en el diff de Git
- Separación clara: modelo, informe y metadatos en carpetas distintas
- Equipos pueden trabajar en tablas distintas simultáneamente
- Pull requests con revisión de medidas línea a línea
- Integración nativa con pipelines de CI/CD
- Si falla un archivo, el resto sigue intacto
.pbip vs .pbix — el nuevo formato de proyecto
TMDL no llega solo: viene de la mano del formato .pbip (Power BI Project). Para usar TMDL, necesitas guardar tu archivo como .pbip en lugar de .pbix.
Cuando guardas como .pbip, Power BI Desktop crea una carpeta de proyecto con una estructura organizada. Ya no tienes un único archivo opaco, sino un directorio completo con ficheros de texto separados para cada parte del modelo.
¿Qué contiene un proyecto .pbip?
📄 MiProyecto.pbip ← el archivo raíz que abre Desktop
📁 MiProyecto.Dataset/ ← aquí vive el modelo semántico
📄 definition.pbidataset ← metadatos del dataset
📁 definition/ ← carpeta con los archivos TMDL
📄 model.tmdl ← configuración global del modelo
📄 relationships.tmdl ← todas las relaciones
📁 tables/
📄 Ventas.tmdl ← tabla con columnas y medidas
📄 DimFecha.tmdl
📄 DimCliente.tmdl
📄 _Medidas.tmdl ← tabla de medidas desconectada
📁 MiProyecto.Report/ ← aquí vive el informe visual
📄 definition.pbir
📄 report.json ← layout de páginas y visuales
Estructura de carpetas y archivos
El corazón de todo está en la carpeta definition/ dentro de .Dataset/. Aquí es donde viven los archivos TMDL con la definición completa del modelo.
model.tmdl — la cabecera del modelo
El archivo model.tmdl contiene la configuración global: versión de compatibilidad, cultura (idioma para formatos de fecha y número), modo de almacenamiento por defecto y la referencia a las tablas que forman parte del modelo.
model Model
culture: es-ES
defaultPowerBIDataSourceVersion: powerBI_V3
ref table Ventas
ref table DimFecha
ref table DimCliente
ref table DimProducto
ref table _Medidas
Tabla.tmdl — tablas, columnas y medidas juntas
Cada tabla tiene su propio archivo .tmdl y contiene todo lo relacionado con ella: columnas, columnas calculadas, medidas y la consulta M de la fuente de datos. Todo junto, bien organizado e indentado.
table Ventas
lineageTag: a1b2c3d4-e5f6-...
column FechaID
dataType: int64
lineageTag: ...
summarizeBy: none
sourceColumn: FechaID
annotation SummarizationSetBy = Automatic
column Importe
dataType: decimal
lineageTag: ...
summarizeBy: sum
sourceColumn: Importe
formatString: #,##0.00 "€"
measure 'Total Ventas' =
SUM(Ventas[Importe])
lineageTag: ...
formatString: #,##0.00 "€"
measure '# Transacciones' =
COUNTROWS(Ventas)
lineageTag: ...
formatString: #,##0
measure 'Ticket Medio' =
DIVIDE([Total Ventas], [# Transacciones])
lineageTag: ...
formatString: #,##0.00 "€"
partition Ventas = m
mode: import
source =
let
Origen = Sql.Database("servidor", "base_datos"),
Tabla = Origen{[Schema="dbo",Item="Ventas"]}[Data]
in
Tabla
annotation PBI_ResultType = Table
relationships.tmdl — todas las relaciones
Las relaciones del modelo viven todas juntas en un único archivo, lo que facilita revisarlas de un vistazo.
relationship Ventas_Fecha
fromTable: Ventas
fromColumn: FechaID
toTable: DimFecha
toColumn: FechaID
relationship Ventas_Cliente
fromTable: Ventas
fromColumn: ClienteID
toTable: DimCliente
toColumn: ClienteID
relationship Ventas_Producto
fromTable: Ventas
fromColumn: ProductoID
toTable: DimProducto
toColumn: ProductoID
Sintaxis TMDL — lo esencial
TMDL tiene una sintaxis limpia basada en indentación, similar a Python o YAML. No hay llaves ni punto y coma: la jerarquía se define por los espacios.
Tipos de objetos en TMDL
| Objeto | Palabra clave | Descripción |
|---|---|---|
| Modelo | model |
Configuración raíz del modelo: cultura, versión, refs a tablas |
| Tabla | table |
Define una tabla con sus columnas, medidas y particiones |
| Columna regular | column |
Columna importada de la fuente de datos |
| Columna calculada | column + = <expresión DAX> |
Columna cuyo valor se calcula con DAX |
| Medida | measure |
Medida DAX. El nombre puede ir entre comillas si tiene espacios |
| Jerarquía | hierarchy |
Jerarquía de navegación con niveles (level) |
| Relación | relationship |
Define la relación entre dos tablas (from → to) |
| Partición | partition |
Define la fuente de datos (M, DAX o M incremental) |
| Rol de seguridad | role |
Define un rol RLS con sus filtros DAX por tabla |
Columna calculada
column 'Año Fiscal'
dataType: int64
lineageTag: ...
summarizeBy: none
=
IF(
MONTH(Ventas[Fecha]) >= 9,
YEAR(Ventas[Fecha]) + 1,
YEAR(Ventas[Fecha])
)
Jerarquía
hierarchy 'Jerarquía Temporal'
lineageTag: ...
level Año
lineageTag: ...
column: Año
level Trimestre
lineageTag: ...
column: Trimestre
level Mes
lineageTag: ...
column: MesNombre
Rol de seguridad (RLS)
role 'Ventas por Región'
modelPermission: read
tablePermission DimRegion =
[Email] = USERPRINCIPALNAME()
TMDL en Power BI Desktop
Desktop ofrece dos formas de trabajar con TMDL: una vista integrada dentro de la propia aplicación para editar el modelo sin salir de ella, y el formato .pbip que expone los archivos TMDL en el sistema de archivos para trabajar con VS Code y Git.
🪟 Vista TMDL — el editor integrado en Desktop
Power BI Desktop incluye una vista TMDL nativa: una pestaña en el panel de vistas izquierdo (junto a Report, Data y Model) que muestra el TMDL completo del modelo actual directamente en la aplicación. No necesitas salir a ningún editor externo.
Lectura en tiempo real
Verás el TMDL generado del modelo tal como está en ese momento: todas las tablas, medidas, columnas y relaciones en formato de texto.
Edición directa
Puedes modificar el TMDL directamente en el editor. Al aplicar los cambios, Desktop los valida y actualiza el modelo. Si hay errores de sintaxis, te avisa antes de aplicar.
Sin formato .pbip obligatorio
La vista TMDL funciona aunque trabajes con .pbix. Es el camino más rápido para ver y retocar el TMDL sin cambiar tu flujo de trabajo habitual.
Perfecta para auditar
Ideal para revisar cómo ha quedado definida una medida, verificar una expresión M de una partición o comprobar la cardinalidad de una relación sin navegar por los paneles visuales.
📁 Formato .pbip — para trabajar con VS Code y Git
Si quieres aprovechar todo el potencial de TMDL (control de versiones, colaboración en equipo, CI/CD), el siguiente nivel es guardar el proyecto en formato .pbip. Esto genera una carpeta con todos los archivos TMDL en disco, que puedes abrir en VS Code y versionar con Git.
Guarda como .pbip
Ve a Archivo → Guardar como y elige el tipo Power BI Project (.pbip). Desktop crea una carpeta de proyecto con los archivos TMDL organizados.
Abre la carpeta en VS Code
Con code . desde la carpeta del proyecto, o arrastrándola a VS Code. Verás inmediatamente los archivos .tmdl de cada tabla, las relaciones y la configuración del modelo.
Inicia Git y conecta al repositorio
Ejecuta git init y conecta la carpeta a tu repositorio remoto en Azure DevOps o GitHub. Crea un .gitignore para excluir los datos cacheados.
Edita en VS Code, guarda, y Desktop recarga
Modifica cualquier archivo TMDL desde VS Code (corrige una fórmula, añade una medida...). Al volver a Desktop con el proyecto abierto, detecta los cambios y te ofrece recargar.
Commit con diffs legibles
Cada vez que guardas cambios en el modelo, puedes hacer commit en Git. El diff mostrará exactamente qué líneas de TMDL cambiaron — perfectamente legible para code reviews.
¿Qué pasa con los datos en modo importación?
Cuando usas el modo de importación con .pbip, los datos se cachean en un archivo .abf dentro de la carpeta del proyecto. Puede pesar gigas, así que siempre hay que excluirlo de Git:
# Datos cacheados (pueden ser muy pesados)
*.abf
*.idf
# Archivos de usuario locales
.pbi/localSettings.json
TMDL en Power BI Service ✨ Nuevo
¡Una de las novedades más esperadas!
Microsoft ha añadido recientemente la posibilidad de editar modelos semánticos directamente desde Power BI Service usando TMDL, sin necesidad de abrir Desktop. Esto abre la puerta a flujos de trabajo completamente en la nube.
La integración de TMDL en el Service se materializa principalmente a través de Git Integration en los Workspaces de Fabric/Power BI Premium. Esta funcionalidad conecta tu workspace directamente con una rama de un repositorio de Azure DevOps o GitHub.
Git Integration en Workspaces
Conectar workspace a Git
Desde la configuración del workspace puedes conectarlo a un repositorio de Azure DevOps o GitHub. El Service sincroniza los artefactos del workspace con los archivos TMDL del repo.
Commit desde el Service
Cuando alguien publica cambios en un modelo semántico desde el Service, esos cambios se pueden hacer commit directamente al repositorio Git como archivos TMDL.
Update desde Git
Cuando hay cambios en el repositorio (por ejemplo, alguien hizo merge de un PR), el workspace puede actualizar su estado haciendo un "Update from Git" desde la interfaz del Service.
Estado de sincronización
El Service muestra el estado de cada artefacto: sincronizado, con conflictos, pendiente de commit o desactualizado respecto al repo. Perfectamente visual.
El flujo completo Desktop → Git → Service
Desarrollas en Desktop con .pbip
Creas o modificas el modelo en Desktop. Los archivos TMDL se actualizan automáticamente en la carpeta del proyecto.
Haces commit y push a Git
Commitas los cambios TMDL a tu rama y la subes al repositorio remoto en Azure DevOps o GitHub.
Pull Request y revisión de código
El equipo revisa las fórmulas DAX y los cambios en el modelo antes de aprobar el merge a la rama de producción.
El workspace del Service se actualiza
Una vez aprobado el merge, el workspace de producción en el Service detecta los cambios y puedes hacer "Update from Git" para aplicarlos. O puedes automatizarlo con un pipeline.
Los usuarios ven el modelo actualizado
Sin interrupciones manuales: el modelo se actualiza de forma controlada, trazable y reversible si algo sale mal.
Casos de uso reales
TMDL no es solo una curiosidad técnica. Hay escenarios muy concretos donde cambia radicalmente la forma de trabajar.
Equipos de BI empresariales
Varios analistas trabajan en el mismo modelo. Cada uno tiene su rama en Git. Los merges y revisiones se gestionan como en cualquier equipo de desarrollo de software.
CI/CD para modelos
Pipelines automatizados que validan la sintaxis TMDL, comprueban que las medidas compilan y despliegan el modelo en distintos entornos (dev → test → prod) sin intervención manual.
Auditoría y compliance
Historial completo de cada cambio en cada medida. Para sectores regulados (banca, seguros), poder demostrar quién cambió un KPI y cuándo tiene un valor enorme.
Testing de modelos
Con herramientas como Tabular Editor o scripts de Python puedes cargar el TMDL y ejecutar tests automatizados sobre las medidas antes de hacer deploy.
Code review de DAX
Al revisar un Pull Request, el revisor ve exactamente qué cambió en una medida DAX, puede comentar líneas concretas y pedir aclaraciones antes de aprobar.
Generación de modelos
Scripts que generan automáticamente archivos TMDL a partir de plantillas o metadatos. Útil para crear modelos con patrones repetitivos de forma masiva.
Buenas prácticas
Añade .abf y .idf al .gitignore
Los archivos de caché de datos pueden pesar gigas. No hay ninguna razón para versionarlos en Git. Define siempre un .gitignore desde el primer día del proyecto.
Organiza las medidas en una tabla desconectada
Crea una tabla _Medidas (o por área: _Ventas, _Finanzas) sin columnas ni datos. En TMDL esto queda muy claro y separado de las tablas de hechos.
Escribe buenos mensajes de commit
Un commit en un modelo TMDL debería decir qué cambió y por qué: "fix: corrige fórmula Ticket Medio excluye devoluciones" en lugar de "cambios modelo".
Usa Tabular Editor junto con TMDL
Tabular Editor entiende TMDL nativamente y ofrece validación, autocompletado y scripts de automatización. Es la herramienta complementaria perfecta para cualquier proyecto .pbip.
Define una estrategia de ramas clara
Por ejemplo: main para producción, develop para integración, y ramas de feature como feature/medidas-margen. Igual que en desarrollo de software.
No edites TMDL y Desktop a la vez
Si editas un archivo .tmdl manualmente mientras Desktop tiene el proyecto abierto, puede haber conflictos al guardar. Cierra Desktop, edita el TMDL, y luego vuelve a abrir. O usa la opción de recargar en Desktop.
Formatea las medidas largas con saltos de línea
TMDL respeta los saltos de línea dentro de las expresiones DAX. Aprovéchalo para escribir medidas complejas con indentación legible, igual que harías en un editor DAX.