¡Jueves de post! Y hoy vengo con un paréntesis sobre los cálculos
visuales, y es para abrir otro hilo con la vista TMDL.
Lo primero de todo, ¿qué significa TMDL? Si nos vamos como siempre a la página oficial de Microsoft nos dice lo siguiente:
El lenguaje de definición de modelos tabulares (TMDL) es una sintaxis de definición del modelo de objetos para los modelos de datos tabulares.
¿¿¿What???
¡Tranquilos! Que lo vamos a traducir a nuestro
lenguaje.
Lo primero que debemos hacer es tener instalada la última versión de Microsoft Power BI Desktop, que actualmente corresponde a Enero 2025. ¿Cómo sabemos que versión tenemos? Acordaros que para ello hacemos clic sobre la opción de “Ayuda” de la cinta de opciones y a continuación en “Acerca de”:
Y se nos abre la siguiente ventana emergente y nos tenemos que fijar donde nos dice “Versión”:
Una vez instalada la última versión, debemos de tener activada la característica de “Versión Preeliminar”. Para ello, hacemos clic sobre el engranaje de la parte inferior derecha:
Y se nos abre la ventana de “Opciones”. Vamos a la opción de “Características de versión preliminar” y activamos la opción de “Vista TMDL”:
Reiniciamos Power BI Desktop y al arrancar vemos una nueva opción en el panel lateral izquierdo:
Hacemos clic sobre ella, y vemos la siguiente ventana:
Como podemos ver es muy similar a la vista de consultas DAX, pero con la diferencia que aquí NO usamos DAX.
Lo primero que vamos hacer es empezar a familiarizarnos con esta vista y manera de trabajar y para ello vamos hacer caso a lo que nos dice la pantalla de la vista TMDL:
Por lo que, si vamos a la opción del modelo, desplegamos las tablas y arrastramos directamente la tabla de dimensión DimCurrency, si nos rellena de manera automática con lo siguiente:
Vamos a ir desglosándolo poco a poco para no abrumarnos. Para ello, vamos a coger las primeras líneas:
createOrReplace
table DimCurrency
lineageTag: 9119a229-4568-4cc5-ba0d-5df216a337ca
column CurrencyKey
dataType: int64
formatString: 0
lineageTag: 0279a1a3-cb22-432c-b578-af0e947eaf8b
summarizeBy: none
sourceColumn: CurrencyKey
annotation SummarizationSetBy = Automatic
createOrReplace: es una instrucción de TMDL que indica que, si la tabla o columna ya existe, la va a reemplazar con la definición que sigue en el script. Si no existe, la crea. Es una especie de “upsert” (update or insert) para el objeto que se define a continuación.
table DimCurrency: Aquí declaramos la tabla DimCurrency, Todo lo que esté dentro de la indentación, es decir, todo lo que venga a continuación de este código en el nivel, forma parte de la definición de esta tabla.
lineageTag: El lineageTag es un GUID (identificador único) que Power BI y Analysis Services usan para llevar un historial y un seguimiento del objeto. Este identificador permite que, aunque cambie el nombre de la tabla en el futuro, las dependencias o vínculos no se rompan, ya que internamente se reconocería por el lineageTag, por lo que aquí debemos usar la premisa: “No toques, si funciona porque tocas”.
column CurrencyKey: Dentro de la tabla DimCurrency, declaramos la columna CurrencyKey.
Los siguientes datos, como podéis ver, están desplazados mediante una sangría,
eso nos indica que pertenecen a la jerarquía de Column
dataType: int64: Definimos el tipo de datos de la columna es un entero de 64 bits
formatString: 0: Esta propiedad define cómo se mostrará el valor de la columna al usuario cuando se consuma en informes o tablas en Power BI. El valor “0” indica que se mostrará como un número entero sin decimales.
lineageTag: De nuevo, un GUID que, al igual que en la tabla, se utiliza para mantener la referencia interna de la columna, permitiendo cambios de nombre sin que se pierdan las relaciones en el modelo.
summarizeBy: none: Esta propiedad determina la agregación por defecto que se aplicaría a la columna en las visualizaciones de Power BI (cuando arrastras la columna a un visual, qué hace por defecto). “None” indica que, por defecto, no se hará ninguna agregación.
sourceColumn: CurrencyKey: Señala el nombre de la columna en la fuente de datos subyacente. Es el mapeo entre la columna en el modelo tabular y el campo físico en la base de datos o archivo de origen.
annotation SummarizationSetBy = Automatic: Las anotaciones (annotations) en TMDL son metadatos adicionales que se agregan para describir o influir en el comportamiento de un objeto.
Y el resto de las columnas, tienen los mismos campos pero puede que con configuraciones diferentes, por ejemplo, un texto tendrá como tipo “string” y no “Int64”.
Visto esto, lanzo una pregunta, ¿podríamos cambiar los tipos de datos del modelo desde aquí? La respuesta es un SI con rotundidad. ¿Cómo? De la siguiente manera:
1. Sobre esta misma columna en vez de querer que sea tipo entero queremos que sea decimal. Para ello, en la línea “dataType” escribimos “decimal”.
Y como podemos ver, cuando empezamos a escribir, ya directamente nos indica la
manera de que debemos escribirlo. Ahora, si nos fijamos bien, en la parte
superior izquierda se no ha habilitado el botón de “Aplicar”. Le damos y
esperamos a que se ejecuten los cambios:
Y si vamos ahora a la vista de datos y seleccionamos la columna en cuestión, vemos:
Que se nos ha cambiado el tipo de datos a decimal. Esto nos abre las puertas a cambios masivos de datos sin necesidad de ir uno a uno en la interfaz. Que significa… ahorro de tiempo.
Si nos desplazamos hacia abajo en el script, llegamos al siguiente fragmento de código:
partition DimCurrency = m
mode: import
queryGroup: Dimensiones
source =
let
Origen = Sql.Database(Servidor, Contoso, [CreateNavigationProperties=false]),
dbo_DimCurrency = Origen{[Schema="dbo",Item="DimCurrency"]}[Data],
#"Otras columnas quitadas" = Table.SelectColumns(dbo_DimCurrency,{"CurrencyKey", "CurrencyLabel", "CurrencyName", "CurrencyDescription"})
in
#"Otras columnas quitadas"
¿Qué es lo que ven mis ojos? ¿Código M? Sí, entre otras cosas. Vamos paso a paso como antes:
partition DimCurrency = m : “Partition” Indica que estás definiendo una partición (o un conjunto de datos) que alimenta la tabla DimCurrency y el “= m” es una convención que señala que el código que define la fuente de la partición está escrito en el lenguaje M.
mode: import: Esto declara que la partición se cargará en modo de importación, es decir, los datos se extraen y se almacenan en el modelo
queryGroup: Dimensiones: Agrupa esta consulta (partición) dentro de un grupo en Power Query llamado “Dimensiones”. ¿Y esto? ¿Es tan listo que sabe que esto es una dimensión? No, a lo que se refiere es que pertenece al grupo creado en Power Query de “Dimensiones”
Source: Este bloque es el código M que define de dónde se obtienen los datos y qué transformaciones se aplican.
En definitiva, podemos realizar cambios en los grupos de las consultas e incluso modificar el código M. Si por ejemplo, en vez de “Dimensiones” el queryGroup, especificamos “Hechos” y aplicamos los cambios. Vemos en Power Query que la tabla DimCurrency se encuentra alojada en el grupo “Hechos”:
Pero no sólo eso, sino que también podemos incluir la descripción de la tabla al comienzo de todo el script para describir lo que es la tabla (Atención: esto es una buena práctica y debemos comentar todo lo que sea posible). ¿Cómo comentamos o le añadimos la descripción? De la siguiente manera:
createOrReplace
/// Dimensión de moneda del modelo
table DimCurrency
lineageTag: 9119a229-4568-4cc5-ba0d-5df216a337ca
Justo después de la instrucción createOrReplace escribimos tres /// y el texto que deseemos. Aplicamos los cambios, y vamos a Power Query:
Y vemos en las propiedades de la consulta como en el tooltip emergente, el texto
descriptivo que acabamos de escribir.
También podemos comentar el código M, modificarlo o crearlo. (Una auténtica pasada).
Y ya, por último, tenemos estas dos líneas de código:
annotation PBI_NavigationStepName = Navegación : Indica el nombre del paso de navegación dentro de Power Query, o el modo en que se mostrará el paso en la interfaz gráfica. “Navegación” es el valor que Power BI mostrará en la lista de pasos de la consulta cuando se abra la vista de Power Query. Esto se suele definir automáticamente cuando conectas a una base de datos y seleccionas una tabla o una vista específica, y Power Query crea un paso de navegación para indicar de dónde vienen los datos. Pero lo podemos renombrar también si queremos:
annotation PBI_NavigationStepName = CambioNombre
Y obtenemos como resultado:
annotation PBI_ResultType = Table: Nos indica que el objeto o la salida final de esta consulta/partición es de tipo Tabla. Puede usarse para que el entorno de Power BI sepa que debe tratar el resultado de la consulta como un conjunto de filas y columnas, y no como, por ejemplo, un valor único o una lista.
Y hasta aquí el primer post de
unos cuantos que creo que saldrán sobre la vista TMDL.¿Qué os parece de momento la vista? Spoiler: A mi un bombazo!
Nos vemos en los datos!!