Lenguaje de definición de modelos tabulares (TMDL)
se aplica a: SQL Server 2016 y versiones posteriores de Analysis Services Azure Analysis Services Fabric/Power BI Premium
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 en el nivel de compatibilidad 1200 o superior.
Entre los elementos clave de TMDL se incluyen:
- Compatibilidad completa con toda la modelo de objetos tabulares (TOM). Cada objeto TMDL expone las mismas propiedades que TOM.
- Basado en texto y optimizado para la interacción y legibilidad humanas. TMDL usa una sintaxis gramatical similar a YAML. Cada objeto TMDL se representa en texto con delimitadores mínimos y usa sangría para marcar las relaciones de elementos primarios y secundarios.
- Mejor experiencia de edición, especialmente en las propiedades con expresiones insertadas de diferentes tipos de contenido, como La expresión de análisis de datos (DAX) y M.
- Mejor para la colaboración debido a su representación de carpeta en la que cada objeto de modelo tiene una representación de archivo individual, lo que facilita el control de código fuente.
Un aspecto importante de TMDL es el uso de sangría de espacios en blanco para indicar una estructura de objetos TOM. En el ejemplo siguiente se muestra lo fácil que es representar un modelo tabular al usar TMDL:
database Sales
compatibilityLevel: 1567
model Model
culture: en-US
table Sales
partition 'Sales-Partition' = m
mode: import
source =
let
Source = Sql.Database(Server, Database)
…
measure 'Sales Amount' = SUMX('Sales', 'Sales'[Quantity] * 'Sales'[Net Price])
formatString: $ #,##0
column 'Product Key'
dataType: int64
isHidden
sourceColumn: ProductKey
summarizeBy: None
column Quantity
dataType: int64
isHidden
sourceColumn: Quantity
summarizeBy: None
column 'Net Price'
dataType: int64
isHidden
sourceColumn: "Net Price"
summarizeBy: none
table Product
partition 'Product-Partition' = m
mode: import
source =
let
Source = Sql.Database(Server, Database),
…
column 'Product Key'
dataType: int64
isKey
sourceColumn: ProductKey
summarizeBy: none
relationship cdb6e6a9-c9d1-42b9-b9e0-484a1bc7e123
fromColumn: Sales.'Product Key'
toColumn: Product.'Product Key'
role Role_Store1
modelPermission: read
tablePermission Store = 'Store'[Store Code] IN {1,10,20,30}
expression Server = "localhost" meta [IsParameterQuery=true, Type="Text", IsParameterQueryRequired=true]
expression Database = "Contoso" meta [IsParameterQuery=true, Type="Text", IsParameterQueryRequired=true]
Estructura de carpetas TMDL
A diferencia de TMSL, TMDL usa una estructura de carpetas. La estructura de carpetas predeterminada solo tiene un nivel de subcarpetas, todo ello con archivos .tmdl dentro de:
- Culturas
- Perspectivas
- Papeles
- Mesas
Y archivos raíz para:
- base de datos
- modelo
- Relaciones
- Expresiones
- orígenes de datos
Este es un ejemplo de una carpeta TMDL:
Las definiciones incluyen:
- Un archivo para la definición de la base de datos.
- Un archivo para la definición del modelo.
- Un archivo para todos los orígenes de datos en el modelo.
- Un archivo para todas las expresiones del modelo.
- Un archivo para todas las relaciones en el modelo.
- Un archivo para cada esquema lingüístico de referencia cultural.
- Un archivo para cada perspectiva.
- Un archivo para cada rol de.
- Un archivo para cada tabla.
- Todas las propiedades de metadatos internas de las tablas (columna, jerarquías, particiones,...) residen en el archivo TMDL de la tabla primaria.
TMDL API
De forma similar a lenguaje de scripting de modelos tabulares (TMSL), hay una clase para controlar la serialización de TMDL. Para TMDL, la clase es TmdlSerializer, en el espacio de nombres Microsoft.AnalysisServices.Tabular.
La clase TmdlSerializer expone métodos para serializar y deserializar documentos TMDL:
Serialización de carpetas
public static void SerializeDatabaseToFolder (Database database, string path)
- Recibe un objeto de base de datos TOM y la ruta de acceso de salida de TMDL.
- Serializa la base de datos TOM en una representación de carpeta TMDL.
Obtenga más información sobre cómo serializar en una carpeta.
public static Database DeserializeDatabaseFromFolder (string path)
- Recibe una ruta de acceso completa a una carpeta TMDL.
- Devuelve la representación del objeto de base de datos TOM de la carpeta TMDL.
Obtenga más información sobre cómo deserializar desde carpetas.
Serialización de cadenas
public static string SerializeObject (MetadataObject object, bool qualifyObject = true)
- Recibe un objeto TOM y devuelve su representación de texto TMDL.
Obtenga más información sobre cómo serializar un objeto en una cadena.
Serialización de secuencias
Puede serializar o deserializar TMDL hacia y desde secuencias, lo que le permite convertir un objeto TOM en flujos de bytes para el almacenamiento, la transmisión y la interoperabilidad entre plataformas. Stream API también permite controlar qué documentos TMDL se cargan y qué documentos TMDL se generan.
La serialización tmDL Stream se controla mediante la clase MetadataSerializationContext.
Obtenga más información sobre cómo serializar hacia y desde TMDL mediante secuencias.
Idioma TMDL
Declaración de objeto
Excepto para el objeto Server, TMDL expone todo el árbol de objetos tom
Un objeto TMDL se declara especificando el tipo de objeto TOM seguido de su nombre. En el ejemplo de código siguiente, cada tipo de objeto: model
, table
, column
va seguido de un nombre de objeto.
model Model
culture: en-US
table Sales
measure Sales = SUM(…)
formatString: $ #,##0
column 'Customer Key'
datatype: int64
sourceColumn: CustomerKey
Los objetos como partition
o measure
tienen propiedades predeterminadas que se pueden asignar después del delimitador igual (=) en la misma línea de la declaración de objeto o en la siguiente línea para una expresión de de varias líneas:
table Sales
partition Sales-Part1 = m
mode: import
...
measure Sales = SUM(…)
formatString: $ #,##0
measure 'Sales (ly)' =
var ly = ...
return ly
formatString: $ #,##0
El nombre del objeto TMDL debe incluirse entre comillas simples (') si incluye cualquiera de los siguientes caracteres:
- Dot (.)
- Equals (=)
- Dos puntos (:)
- Comillas simples (')
- Espacio en blanco ( )
Si un nombre de objeto contiene comillas simples ('), use dos comillas simples para escaparla.
Propiedades del objeto
Las propiedades del objeto se especifican después de la declaración de objeto o la expresión de varias líneas de la propiedad predeterminada del objeto. Los valores de propiedad de objeto se especifican después del delimitador de dos puntos (:). Por ejemplo:
table Sales
lineageTag: e9374b9a-faee-4f9e-b2e7-d9aafb9d6a91
column Quantity
dataType: int64
isHidden
isAvailableInMdx: false
sourceColumn: Quantity
measure 'Sales Amount' =
var result = SUMX(...)
return result
formatString: $ #,##0
displayFolder: " My ""Amazing"" Measures"
Las reglas siguientes se aplican a los valores de propiedad:
El valor debe estar en la misma línea que sigue a los dos puntos y no puede tener varias líneas.
Valores de propiedad text
- Las comillas dobles iniciales y finales son opcionales y se quitan automáticamente durante la serialización.
- Debe incluirse entre comillas dobles (") si el texto contiene espacios en blanco finales o iniciales.
- Cuando se incluye entre comillas dobles, si el valor contiene comillas dobles, use dos comillas dobles para escaparlas (vea
displayFolder
propiedad en el ejemplo de código anterior).
propiedades booleanas se pueden establecer mediante la sintaxis de par clave-valor estándar, como con la propiedad
'isAvailableInMdx'
del ejemplo anterior. También se pueden establecer mediante una sintaxis de acceso directo donde solo se declara el nombre de propiedad ytrue
está implícito. Vea, por ejemplo, la propiedad 'isHidden' en el ejemplo anterior.
Referencias de objeto con nombre
Algunas propiedades de objeto contienen referencias a otros objetos de modelo, por ejemplo:
- Referencia de columna en niveles de jerarquía.
- referencia sortByColumn en cada columna de tabla.
- Referencia de tabla,columna/medida en perspectivas.
En TMDL, las referencias se realizan con el nombre del objeto y siguen el mismo escape y comillas simples (') que incluye los requisitos de declaración de objeto. En el ejemplo de código siguiente, verá propiedades de objeto que contienen una referencia a otro objeto: column.sortByColumn
, level.column
, perspectiveMeasure.measure
y perspectiveTable.table
.
table Product
column Category
sortByColumn: 'Category Order'
hierarchy 'Product Hierarchy'
level Category
column: Category
perspective Product
perspectiveTable Product
perspectiveMeasure '# Products'
Si es necesario para hacer referencia a un nombre completo, TMDL usa notación de punto para hacer referencia a un objeto, por ejemplo: 'Table 1'.'Column 1'
Objetos secundarios
El árbol de objetos TOM contiene objetos secundarios en muchos lugares y en distintos niveles. Por ejemplo:
- Un objeto de modelo contiene objetos de tabla, rol y expresión.
- Un objeto table contiene objetos de columna, medida y jerarquía.
TMDL no declara colecciones secundarias explícitamente. En su lugar, todos los elementos secundarios aplicables dentro del ámbito de su elemento primario respectivo componen implícitamente los elementos de la colección correspondiente. Por ejemplo, todos los elementos de columna dentro del ámbito de una tabla determinada se convierten en elementos de la colección de columnas de esa tabla en TOM, como se muestra aquí:
table Sales
measure 'Sales Amount' = SUMX('Sales', [Quantity] * [Net Price])
measure 'Total Quantity' = SUM('Sales'[Quantity])
measure 'Sales Amount YTD' = TOTALYTD([Sales Amount], 'Calendar'[Date])
Los objetos secundarios no tienen que ser contiguos. Por ejemplo, puede declarar columnas y medidas en cualquier orden e intercalación.
Propiedades predeterminadas
Algunos tipos de objeto tienen una propiedad predeterminada que la mayoría de las veces se tratan como expresiones. La propiedad predeterminada es específica del tipo de objeto. Si procede, el valor de propiedad o la expresión se especifica después del delimitador igual a (=), después de la declaración de sección.
Sintaxis admitida:
- El valor se especifica en la misma línea que el encabezado de sección.
- El valor se especifica como una expresión de varias líneas siguiendo el encabezado de sección.
En el ejemplo de código siguiente, la medida Sales Amount
y la Sales-Partition1
de partición son una sola línea y la Quantity
de medida es de varias líneas:
table Sales
measure 'Sales Amount' = SUM(...)
formatString: $ #,##0
measure Quantity =
var result = SUMX (...)
return result
formatString: #,##0
partition Sales-Partition1 = m
mode: import
source =
let
...
in
finalStep
Expresiones
Hay propiedades de objeto que, al ser una propiedad de texto en TOM, obtienen un análisis especial en TMDL. El texto completo se lee textualmente porque puede incluir caracteres especiales como comillas o corchetes en expresiones M o DAX. Las expresiones pueden ser de varias líneas o de una sola línea. Si hay varias líneas, deben encontrarse en la línea inmediatamente después de la declaración de propiedad o objeto.
Se especifica un valor de expresión en TMDL siguiendo un delimitador igual a (=), como en el ejemplo siguiente:
table Table1
partition 'partition 1' = m
mode: import
source =
let
...
in
finalStep
measure Measure1 = SUM(...)
measure Measure2 =
var result = SUMX (
...
)
return result
formatString: $ #,##0
Las siguientes reglas especiales se aplican a las expresiones:
- Las expresiones de varias líneas deben aplicar sangría a un nivel más profundo a las propiedades del objeto primario y toda la expresión debe estar dentro de ese nivel de sangría.
- Todos los espacios en blanco de sangría externa se quitan más allá del nivel de sangría del objeto primario.
- Se permiten espacios en blanco verticales (líneas en blanco sin espacios en blanco) y se consideran parte de la expresión.
- Se quitan las líneas en blanco finales y los espacios en blanco.
- Para aplicar una sangría diferente o para conservar líneas en blanco finales o espacios en blanco, use las tres líneas inversas (```) envolventes.
- De forma predeterminada, el serializador TMDL se incluirá con acentos versos si el valor de expresión contiene algo que podría provocar una modificación en el recorrido de ida y vuelta (por ejemplo, espacios en blanco finales, líneas en blanco con espacios en blanco).
Las expresiones incluidas con tres acentos inversas (```) son textuales de lectura, incluida la sangría, las líneas en blanco y los espacios en blanco. El delimitador debe aplicarse inmediatamente después del signo igual (=) y la línea que sigue a la expresión y no puede tener nada después, como en el ejemplo siguiente:
table Table1
partition partition1 = m
mode: import
source = ```
let
...
in
finalStep
```
measure Measure1 = ```
var myVar = Today()
…
return result
```
El uso de los tres delimitadores de retroceso (```) es opcional y solo es necesario en situaciones únicas. En la mayoría de las situaciones, el uso de la sangría correcta y la declaración de objeto garantiza el análisis correcto de cualquier expresión que agregue a la propiedad .
Cuando la expresión se incluye dentro de las operaciones inversas, se aplican las reglas siguientes:
- Todo lo que hay entre tres acentos inversas (```) se considera parte de la expresión de varios bloques y no se aplican las reglas de sangría TMDL. El delimitador final determina la sangría dentro de la expresión.
- Se conserva la sangría relativa dentro de la expresión. El delimitador final (```) determina el límite izquierdo de la expresión (vea "Measure1" en el ejemplo anterior).
Las siguientes propiedades se tratan como expresiones:
Tipo de objeto | Propiedad | Lenguaje de expresión |
---|---|---|
Medir | Expresión | DAX |
MPartitionSource | Expresión | M |
CalculatedPartitionSource | Expresión | DAX |
QueryPartitionSource | Consulta | NativeQuery |
CalculationItem | Expresión | DAX |
BasicRefreshPolicy | SourceExpression, PollingExpression | M |
KPI | StatusExpression, TargetExpression, TrendExpression | DAX |
LinguisticMetadata | Contenido | XML o Json |
JsonExtendedProperty | Valor | Json |
FormatStringDefintion | Expresión | DAX |
DataCoverageDefinition | Expresión | DAX |
CalculationGroupExpression | Expresión | DAX |
NamedExpression | Expresión | DAX |
DetailRowsDefinition | Expresión | DAX |
TablePermission | FilterExpression | DAX |
CalculatedColumn | Expresión | DAX |
Propiedades predeterminadas por tipo de objeto
En la tabla siguiente se muestran la propiedad predeterminada y el lenguaje de expresión por tipo de objeto:
Tipo de objeto | Propiedad predeterminada | Lenguaje de expresión |
---|---|---|
Medir | Expresión | DAX |
CalculatedColumn | Expresión | DAX |
CalculationItem | Expresión | DAX |
FormatStringDefinition | Expresión | DAX |
DetailRowsDefinition | Expresión | DAX |
CalculationExpression | Expresión | DAX |
DataCoverageDefinition | Expresión | DAX |
TablePermission | FilterExpression | DAX |
ColumnPermission | MetadataPermission | MetadataPermission Enum |
NamedExpression | Expresión | M |
MPartitionSource | Expresión | M |
CalculatedPartitionSource | Expresión | DAX |
JsonExtendedProperty | Valor | Json |
Anotación | Valor | Mensaje de texto |
StringExtendedProperty | Valor | Mensaje de texto |
DataSource | Tipo | de enumeración dataSourceType de |
Partición | SourceType | enumeración PartitionSourceType |
ChangedProperty | Propiedad | de texto de propiedad de |
ExternalModelRoleMember | MemberType | de enumeración RoleMemberType de |
Cualquier propiedad JSON personalizada (por ejemplo, DataAccessOptions) | Documento JSON | Json |
LinguisticMetadata | Contenido | Json |
Descripciones
TMDL proporciona compatibilidad de primera clase con descripciones. Con fines de documentación del modelo, el procedimiento recomendado es proporcionar descripciones para cada objeto TOM. TMDL trata las descripciones como una propiedad especial con compatibilidad explícita con sintaxis. Siguiendo los ejemplos de muchos otros lenguajes, se especifican descripciones sobre cada declaración de objeto mediante la sintaxis de barra diagonal triple (///).
No se permite ningún espacio en blanco entre el extremo del bloque de descripción y el token de tipo de objeto.
Las descripciones se pueden dividir entre varias líneas. El serializador TMDL divide las descripciones de objetos en varias líneas para mantener las líneas de documento emitidas bajo la longitud máxima. La longitud máxima predeterminada es de 80 caracteres.
/// Table Description
table Sales
/// This is the Measure Description
/// One more line
measure 'Sales Amount'' = SUM(...)
formatString: #,##0
Declaración parcial
TMDL no fuerza la declaración de objeto en el mismo documento. Sin embargo, es similar a clases parciales de C# donde es posible dividir la definición de objeto entre varios archivos. Por ejemplo, puede declarar una definición de tabla en un archivo [table].tmdl y, a continuación, tener todas las medidas de todas las tablas definidas en un único archivo [measures].tmdl, como se muestra aquí:
table Sales
measure 'Sales Amount' = SUM(…)
formatString: $ #,##0
table Product
measure CountOfProduct = COUNTROWS(…)
Para evitar un error de análisis, la misma propiedad no se puede declarar dos veces. Por ejemplo, declarar dos medidas con el mismo nombre para la misma tabla en dos documentos TMDL diferentes produce un error.
Referencias de objeto
Puede hacer referencia a otro objeto TMDL mediante la palabra clave ref seguida del tipo de objeto y el nombre.
Por ejemplo, si serializa un objeto Column mediante la API de serialización de cadenas, el resultado será:
ref table Table1
column Column1
datatype: int64
sourceColumn: Column1
Ordenación de colección determinista
La palabra clave ref también se usa para definir y conservar el orden de recopilación en los recorridos de ida y vuelta de TOM <> TMDL. Es especialmente importante evitar diferencias de control de código fuente en objetos TMDL que se serializan en archivos individuales: tablas, roles, referencias culturales y perspectivas. La palabra clave ref
model Model
ref table Calendar
ref table Sales
ref table Product
ref table Customer
ref table About
ref culture en-US
ref culture pt-PT
ref role 'Stores Cluster 1'
ref role 'Stores Cluster 2'
Se aplican las reglas siguientes:
- Durante la deserialización de TMDL:
- Los objetos a los que se hace referencia en TMDL pero que faltan en el archivo TMDL se omiten.
- Los objetos no a los que se hace referencia, pero con el archivo TMDL existente, se anexan al final de la colección.
- Durante la serialización de TMDL:
- Se hace referencia a todos los objetos de colección de TOM mediante la palabra clave ref
. - Las colecciones con un solo elemento no emiten una referencia.
- Las líneas en blanco no se emiten entre las referencias si el mismo tipo de objeto.
- Se hace referencia a todos los objetos de colección de TOM mediante la palabra clave ref
Delimitadores de valor de propiedad
Solo hay dos delimitadores o símbolos para asignar un valor de propiedad:
Equals (=)
- Se usa en la declaración de objeto con propiedad predeterminada (línea múltiple y única)
- Se usa en cada propiedad de expresión, por ejemplo, partition.expression.
Dos puntos (:)
- Se usa para cada valor de propiedad que no sea de expresión. Incluir propiedades que contienen referencias de modelo.
Sangría
TMDL usa reglas estrictas de sangría de espacios en blanco para indicar la estructura de la jerarquía de TOM. Un documento TMDL usa una sola pestaña de predeterminada regla de sangría.
Cada objeto puede tener tres niveles de sangría:
- Nivel 1: Declaración de objeto
- Nivel 2: Propiedades del objeto
- Nivel 3: expresiones de varias líneas de propiedad de objeto
- Nivel 2: Propiedades del objeto
Dentro de un documento TMDL, la sangría se aplica en los casos siguientes:
Entre un encabezado de sección de objeto y las propiedades del objeto (tabla:> propiedades).
table Sales isHidden lineageTag: 9a48bea0-e5fb-40fa-9e81-f61288e31a02
Entre un objeto y sus objetos secundarios (tabla:> medidas).
table Sales measure 'Sales Amount' = SUMX(...) measure 'Total Quantity' = SUM(...)
Entre un objeto y sus expresiones de varias líneas (tabla -> medida -> expresión).
table Sales measure 'Sales Amount' = var result = SUMX(...) return result formatString: $ #,##0
Las expresiones de varias líneas deben aplicar sangría a un nivel más profundo que las propiedades del objeto y toda la expresión debe estar dentro de ese nivel de sangría (vea expresiones).
No es necesario aplicar sangría a la base de datos ni a los objetos secundarios directos del modelo porque se asumen implícitamente anidados en el modelo raíz o la base de datos:
- modelo
- Mesas
- expresiones compartidas
- Papeles
- Culturas
- Perspectivas
- Relaciones
- orígenes de datos
- grupos de consultas
- anotaciones de nivel de modelo
- propiedades extendidas de nivel de modelo
No seguir estas reglas de sangría genera un error de análisis.
Espacios
TMDL aplica de forma predeterminada las siguientes reglas al espacio en blanco dentro de los valores de propiedad y expresión, cuando no se incluyen entre las comillas inversas (```) o las comillas dobles ("):
- En los valores de propiedad, se recortan los espacios en blanco iniciales y finales.
- En las expresiones, se quitan las líneas de espacio en blanco al final de las expresiones.
- Las líneas de espacios en blanco se recortan a líneas vacías (sin espacios o pestañas).
Cubierta
De forma predeterminada, la API tmDL en el uso de serialización y escritura camelCase, aplicada a:
- Tipos de objeto
- Palabras clave
- Valores de enumeración
Al deserializar/leer, la API tmDL no distingue mayúsculas de minúsculas.
Contenido relacionado
Ahora que conoce TMDL, asegúrese de ver Introducción a TMDL para aprender a obtener e implementar una representación de modelo TMDL de un modelo semántico de Power BI.