Langage de définition de modèle tabulaire (TMDL)
s’applique à : SQL Server 2016 et versions ultérieures Analysis Services Azure Analysis Services Fabric/Power BI Premium
Le langage TMDL (Tabular Model Definition Language) est une syntaxe de définition de modèle objet pour les modèles de données tabulaires au niveau de compatibilité 1200 ou supérieur.
Les éléments clés de TMDL sont les suivants :
- Compatibilité complète avec l’ensemble du modèle objet tabulaire (TOM). Chaque objet TMDL expose les mêmes propriétés que TOM.
- Texte et optimisé pour l’interaction humaine et la lisibilité. TMDL utilise une syntaxe de grammaire similaire à YAML. Chaque objet TMDL est représenté dans du texte avec des délimiteurs minimal et utilise la mise en retrait pour marquer les relations parent-enfant.
- Meilleure expérience de modification, en particulier sur les propriétés avec des expressions incorporées à partir de différents types de contenu, tels que DAX (Data Analysis Expression) et M.
- Mieux pour la collaboration en raison de sa représentation de dossier où chaque objet de modèle a une représentation de fichier individuelle, ce qui le rend plus convivial pour le contrôle de code source.
Un aspect important de TMDL est l’utilisation d’un retrait d’espace blanc pour désigner une structure d’objet TOM. L’exemple suivant montre comment il est facile de représenter un modèle tabulaire lors de l’utilisation de 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]
Structure de dossiers TMDL
Contrairement à TMSL, TMDL utilise une structure de dossiers. La structure de dossiers par défaut n’a qu’un seul niveau de sous-dossiers , tous avec des fichiers .tmdl à l’intérieur :
- Cultures
- Perspectives
- Rôles
- Tables
Et fichiers racines pour :
- base de données
- modèle
- Relations
- Expressions
- sources de données
Voici un exemple de dossier TMDL :
Les définitions sont les suivantes :
- Un fichier pour la définition de base de données.
- Un fichier pour la définition de modèle.
- Un fichier pour toutes les sources de données dans le modèle.
- Un fichier pour toutes les expressions dans le modèle.
- Un fichier pour toutes les relations dans le modèle.
- Un fichier pour chaque schéma linguistique de culture.
- Un fichier pour chaque perspective.
- Un fichier pour chaque rôle.
- Un fichier pour chaque table.
- Toutes les propriétés de métadonnées internes des tables (colonnes, hiérarchies, partitions,...) se trouvent dans le fichier TMDL de la table parente.
TMDL API
Comme pour langage TMSL (Tabular Model Scripting Language), il existe une classe pour gérer la sérialisation TMDL. Pour TMDL, la classe est tmdlSerializer, sous l’espace de noms Microsoft.AnalysisServices.Tabular.
La classe TmdlSerializer expose des méthodes pour sérialiser et désérialiser des documents TMDL :
Sérialisation des dossiers
public static void SerializeDatabaseToFolder (Database database, string path)
- Reçoit un objet de base de données TOM et le chemin de sortie TMDL.
- Sérialise la base de données TOM dans une représentation de dossier TMDL.
En savoir plus sur la sérialisation vers un dossier.
public static Database DeserializeDatabaseFromFolder (string path)
- Reçoit un chemin d’accès complet à un dossier TMDL.
- Retourne la représentation d’objet de base de données TOM du dossier TMDL.
En savoir plus sur la désérialisation à partir de dossiers.
Sérialisation de chaîne
public static string SerializeObject (MetadataObject object, bool qualifyObject = true)
- Reçoit un objet TOM et retourne sa représentation textuelle TMDL.
En savoir plus sur la sérialisation d’un objet vers une chaîne.
Sérialisation de flux
Vous pouvez sérialiser/désérialiser TMDL vers/depuis des flux, ce qui vous permet de convertir un objet TOM en flux d’octets pour le stockage, la transmission et l’interopérabilité entre plateformes. L’API Stream vous permet également de contrôler quels documents TMDL sont chargés et quels documents TMDL sont générés.
La sérialisation tmDL Stream est gérée par la classe MetadataSerializationContext.
En savoir plus sur la sérialisation vers/à partir de TMDL à l’aide de flux.
Langage TMDL
Déclaration d’objet
À l’exception de l’objet Server, TMDL expose l’arborescence d’objets TOM Database dans l’espace de noms microsoft.AnalysisServices.Tabulaire .
Un objet TMDL est déclaré en spécifiant le type d’objet TOM suivi de son nom. Dans l’exemple de code suivant, chaque type d’objet : model
, table
, column
est suivi d’un nom d’objet.
model Model
culture: en-US
table Sales
measure Sales = SUM(…)
formatString: $ #,##0
column 'Customer Key'
datatype: int64
sourceColumn: CustomerKey
Les objets tels que partition
ou measure
ont propriétés par défaut qui peuvent être affectées après le délimiteur égal (=) dans la même ligne de la déclaration d’objet ou dans la ligne suivante pour une expression de multiligne:
table Sales
partition Sales-Part1 = m
mode: import
...
measure Sales = SUM(…)
formatString: $ #,##0
measure 'Sales (ly)' =
var ly = ...
return ly
formatString: $ #,##0
Le nom de l’objet TMDL doit être placé entre guillemets simples (') s’il inclut l’un des caractères suivants :
- Point (.)
- Égal (=)
- Deux-points (:)
- Guillemet unique (')
- Espace blanc ( )
Si un nom d’objet contient des guillemets simples ('), utilisez deux guillemets simples pour l’échapper.
Propriétés de l’objet
Les propriétés d’objet sont spécifiées après la déclaration d’objet ou l’expression multiligne de propriété par défaut de l’objet. Les valeurs de propriété d’objet sont spécifiées en suivant le signe deux-points (:) délimiteur. Par exemple:
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"
Les règles suivantes s’appliquent aux valeurs de propriété :
La valeur doit se trouver dans la même ligne qui suit le signe deux-points et ne peut pas avoir plusieurs lignes.
Valeurs de propriété de texte
- Les guillemets doubles de début et de fin sont facultatifs et automatiquement supprimés pendant la sérialisation.
- Doit être placé entre guillemets doubles (") si le texte contient des espaces blancs de fin ou de début.
- Lorsqu’elle est placée entre guillemets doubles, si la valeur contient des guillemets doubles, utilisez deux guillemets doubles pour les échapper (voir
displayFolder
propriété dans l’exemple de code ci-dessus).
propriétés booléennes pouvez être définies à l’aide de la syntaxe de paire clé/valeur standard, comme avec la propriété
'isAvailableInMdx'
dans l’exemple précédent. Ils peuvent également être définis à l’aide d’une syntaxe de raccourci où seul le nom de la propriété est déclaré ettrue
est implicite. Consultez, par exemple, la propriété « isHidden » dans l’exemple précédent.
Références d’objets nommés
Certaines propriétés d’objet contiennent des références à d’autres objets de modèle, par exemple :
- Référence de colonne dans les niveaux de hiérarchie.
- référence sortByColumn dans chaque colonne de table.
- Référence table/colonne/mesure dans les perspectives.
Dans TMDL, les références sont faites à l’aide du nom de l’objet et suivent les mêmes échappements et guillemets simples (') englobant les exigences de déclaration d’objet. Dans l’exemple de code suivant, vous voyez les propriétés d’objet qui contiennent une référence à un autre objet : column.sortByColumn
, level.column
, perspectiveMeasure.measure
et perspectiveTable.table
.
table Product
column Category
sortByColumn: 'Category Order'
hierarchy 'Product Hierarchy'
level Category
column: Category
perspective Product
perspectiveTable Product
perspectiveMeasure '# Products'
Si nécessaire pour référencer un nom complet, TMDL utilise notation point pour référencer un objet, par exemple : 'Table 1'.'Column 1'
Objets enfants
L’arborescence d’objets TOM contient des objets enfants dans de nombreux endroits et à différents niveaux. Par exemple:
- Un objet de modèle contient des objets de table, de rôle et d’expression.
- Un objet table contient des objets de colonne, de mesure et de hiérarchie.
TMDL ne déclare pas explicitement les collections enfants. Au lieu de cela, tous les éléments enfants applicables dans la portée de leur parent respectif composent implicitement les éléments de la collection correspondante. Par exemple, tous les éléments de colonne dans l’étendue d’une table particulière deviennent des éléments de la collection de colonnes de cette table dans TOM, comme illustré ici :
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])
Les objets enfants n’ont pas besoin d’être contigus. Par exemple, vous pouvez déclarer des colonnes et des mesures dans n’importe quel ordre et entremêlés.
Propriétés par défaut
Certains types d’objets ont une propriété par défaut que la plupart du temps sont traités comme expressions. La propriété par défaut est spécifique au type d’objet. Le cas échéant, la valeur ou l’expression de propriété est spécifiée à la suite du délimiteur égal (=) - après la déclaration de section.
Syntaxe prise en charge :
- La valeur est spécifiée sur la même ligne que l’en-tête de section.
- La valeur est spécifiée en tant qu’expression multiligne suivant l’en-tête de section.
Dans l’exemple de code suivant, les Sales Amount
de mesure et les Sales-Partition1
de partition sont une seule ligne et Quantity
de mesure est multiligne :
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
Expressions
Il existe des propriétés d’objet qui, tout en étant une propriété de texte dans TOM, obtiennent une analyse spéciale dans TMDL. Le texte entier est lu en détail, car il peut inclure des caractères spéciaux tels que des guillemets ou des crochets dans des expressions M ou DAX. Les expressions peuvent être multilignes ou monolignes. Si plusieurs lignes doivent être situées dans la ligne immédiatement après la déclaration de propriété ou d’objet.
Une valeur d’expression dans TMDL est spécifiée en suivant un délimiteur égal (=), comme dans l’exemple suivant :
table Table1
partition 'partition 1' = m
mode: import
source =
let
...
in
finalStep
measure Measure1 = SUM(...)
measure Measure2 =
var result = SUMX (
...
)
return result
formatString: $ #,##0
Les règles spéciales suivantes s’appliquent aux expressions :
- Les expressions multilignes doivent être mises en retrait un niveau plus profond aux propriétés de l’objet parent et l’expression entière doit se trouver dans ce niveau de retrait.
- Tous les espaces blancs de retrait externe sont supprimés au-delà du niveau mis en retrait de l’objet parent.
- Les espaces blancs verticaux (lignes vides sans espaces blancs) sont autorisés et sont considérés comme faisant partie de l’expression.
- Les lignes vides de fin et les espaces blancs sont supprimés.
- Pour appliquer une mise en retrait différente ou pour conserver les lignes vides ou les espaces blancs de fin, utilisez les trois backticks (```) englobants.
- Par défaut, le sérialiseur TMDL se place avec des backticks si la valeur de l’expression contient tout ce qui peut entraîner une modification en aller-retour (par exemple, les espaces blancs de fin, les lignes vides avec des espaces blancs).
Les expressions entourées de trois backticks (```) sont lues en détail, notamment la mise en retrait, les lignes vides et les espaces blancs. Le délimiteur doit être appliqué immédiatement après le signe égal (=) et la ligne qui suit l’expression et ne peut rien avoir après elle, comme dans l’exemple suivant :
table Table1
partition partition1 = m
mode: import
source = ```
let
...
in
finalStep
```
measure Measure1 = ```
var myVar = Today()
…
return result
```
L’utilisation des trois séparateurs backticks (```) est facultative et uniquement nécessaire dans des situations uniques. Pour la plupart des situations, l’utilisation de la mise en retrait correcte et de la déclaration d’objet garantit l’analyse correcte de l’expression que vous ajoutez à la propriété.
Lorsque l’expression est placée entre des backticks, les règles suivantes s’appliquent :
- Tous les éléments entre trois backticks (```) sont considérés comme faisant partie de l’expression multi-bloc et des règles de mise en retrait TMDL ne sont pas appliqués. Le délimiteur de fin détermine la mise en retrait dans l’expression.
- La mise en retrait relative dans l’expression est conservée. Le délimiteur de fin (```) détermine la limite de gauche de l’expression (voir « Measure1 » dans l’exemple précédent).
Les propriétés suivantes sont traitées comme des expressions :
Type d’objet | Propriété | Langage d’expression |
---|---|---|
Mesurer | Expression | DAX |
MPartitionSource | Expression | M |
CalculatedPartitionSource | Expression | DAX |
QueryPartitionSource | Requête | NativeQuery |
CalculationItem | Expression | DAX |
BasicRefreshPolicy | SourceExpression, PollingExpression | M |
KPI | StatusExpression, TargetExpression, TrendExpression | DAX |
LinguisticMetadata | Contenu | XML ou Json |
JsonExtendedProperty | Valeur | Json |
FormatStringDefintion | Expression | DAX |
DataCoverageDefinition | Expression | DAX |
CalculationGroupExpression | Expression | DAX |
NamedExpression | Expression | DAX |
DetailRowsDefinition | Expression | DAX |
TablePermission | FilterExpression | DAX |
CalculatedColumn | Expression | DAX |
Propriétés par défaut par type d’objet
Le tableau suivant présente la propriété et le langage d’expression par défaut par type d’objet :
Type d’objet | Propriété par défaut | Langage d’expression |
---|---|---|
Mesurer | Expression | DAX |
CalculatedColumn | Expression | DAX |
CalculationItem | Expression | DAX |
FormatStringDefinition | Expression | DAX |
DetailRowsDefinition | Expression | DAX |
CalculationExpression | Expression | DAX |
DataCoverageDefinition | Expression | DAX |
TablePermission | FilterExpression | DAX |
ColumnPermission | MetadataPermission | MetadataPermission Enum |
NamedExpression | Expression | M |
MPartitionSource | Expression | M |
CalculatedPartitionSource | Expression | DAX |
JsonExtendedProperty | Valeur | Json |
Annotation | Valeur | SMS |
StringExtendedProperty | Valeur | SMS |
DataSource | Type | Enum DataSourceType |
Partition | SourceType | PartitionSourceType Enum |
ChangedProperty | Propriété | , de texte de propriété |
ExternalModelRoleMember | MemberType | RoleMemberType |
Toute propriété JSON personnalisée (par exemple, DataAccessOptions) | JSON Document | Json |
LinguisticMetadata | Contenu | Json |
Descriptions
TMDL fournit une prise en charge de première classe pour les descriptions. À des fins de documentation de modèle, la meilleure pratique consiste à fournir des descriptions pour chaque objet TOM. TMDL traite les descriptions comme une propriété spéciale avec prise en charge de syntaxe explicite. En suivant les exemples de nombreux autres langages, les descriptions sont spécifiées au-dessus de chaque déclaration d’objet à l’aide d’une syntaxe à barres obliques triples (///).
Aucun espace blanc n’est autorisé entre la fin du bloc de description et le jeton de type d’objet.
Les descriptions peuvent être divisées sur plusieurs lignes. Le sérialiseur TMDL interrompt les descriptions d’objets en plusieurs lignes pour conserver les lignes de document émises sous la longueur maximale. La longueur maximale par défaut est de 80 caractères.
/// Table Description
table Sales
/// This is the Measure Description
/// One more line
measure 'Sales Amount'' = SUM(...)
formatString: #,##0
Déclaration partielle
TMDL ne force pas la déclaration d’objet dans le même document. Toutefois, il est similaire à classes partielles C# où il est possible de fractionner la définition d’objet entre plusieurs fichiers. Par exemple, vous pouvez déclarer une définition de table dans un fichier [table].tmdl, puis avoir toutes les mesures de toutes les tables définies dans un seul fichier [mesures].tmdl, comme illustré ici :
table Sales
measure 'Sales Amount' = SUM(…)
formatString: $ #,##0
table Product
measure CountOfProduct = COUNTROWS(…)
Pour éviter une erreur d’analyse, la même propriété ne peut pas être déclarée deux fois. Par exemple, la déclaration de deux mesures portant le même nom pour la même table dans deux documents TMDL différents entraîne une erreur.
Références d’objet
Vous pouvez référencer un autre objet TMDL à l’aide du mot clé ref
Par exemple, si vous sérialisez un objet Column à l’aide de l’API de sérialisation de chaîne, le résultat sera :
ref table Table1
column Column1
datatype: int64
sourceColumn: Column1
Classement de collection déterministe
Le mot clé ref est également utilisé pour définir et conserver l’ordre de collection sur les aller-retours TOM <> TMDL. Il est particulièrement important d’éviter les différences de contrôle de code source sur les objets TMDL qui sont sérialisés dans des fichiers individuels : tables, rôles, cultures et perspectives. Le mot clé ref est utilisé sur le fichier TMDL de l’objet parent pour déclarer l’ordre des éléments à partir de TOM :
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'
Les règles suivantes sont appliquées :
- Pendant la désérialisation TMDL :
- Les objets référencés dans TMDL, mais avec un fichier TMDL manquant, sont ignorés.
- Les objets non référencés, mais avec le fichier TMDL existant, sont ajoutés à la fin de la collection.
- Pendant la sérialisation TMDL :
- Tous les objets de collection dans TOM sont référencés à l’aide du mot clé ref
. - Les collections avec un seul élément n’émettent pas de référence.
- Les lignes vides ne sont pas émises entre les références si le même type d’objet.
- Tous les objets de collection dans TOM sont référencés à l’aide du mot clé ref
Délimiteurs de valeur de propriété
Il n’existe que deux délimiteurs/symboles pour affecter une valeur de propriété :
Égal (=)
- Utilisé lors de la déclaration d’objet avec propriété par défaut (ligne multiple et unique)
- Utilisé à chaque propriété d’expression , par exemple partition.expression
Deux-points (:)
Indentation
TMDL utilise des règles de retrait d’espace blanc strictes pour la structure de la hiérarchie TOM. Un document TMDL utilise un onglet de unique par défaut règle de retrait.
Chaque objet peut avoir trois niveaux de retrait :
- Niveau 1 - Déclaration d’objet
- Niveau 2 - Propriétés de l’objet
- Niveau 3 - Expressions multilignes de propriété d’objet
- Niveau 2 - Propriétés de l’objet
Dans un document TMDL, la mise en retrait est appliquée dans les cas suivants :
Entre un en-tête de section d’objet et les propriétés de l’objet (table -> propriétés).
table Sales isHidden lineageTag: 9a48bea0-e5fb-40fa-9e81-f61288e31a02
Entre un objet et ses objets enfants (table - mesures>).
table Sales measure 'Sales Amount' = SUMX(...) measure 'Total Quantity' = SUM(...)
Entre un objet et ses expressions multilignes (table -> mesure -> expression).
table Sales measure 'Sales Amount' = var result = SUMX(...) return result formatString: $ #,##0
Les expressions multilignes doivent être mises en retrait d’un niveau plus profond que les propriétés d’objet et l’expression entière doit se trouver dans ce niveau de retrait (voir expressions).
La base de données et les objets enfants directs du modèle n’ont pas besoin d’être mis en retrait, car ils sont implicitement imbriqués sous le modèle racine ou la base de données :
- modèle
- Tables
- expressions partagées
- Rôles
- Cultures
- Perspectives
- Relations
- sources de données
- groupes de requêtes
- Annotations au niveau du modèle
- Propriétés étendues au niveau du modèle
Le fait de ne pas suivre ces règles de retrait génère une erreur d’analyse.
Espaces
TMDL applique par défaut les règles suivantes aux espaces blancs dans les valeurs de propriété et d’expression, lorsqu’elles ne sont pas placées dans des backticks (```) ou des guillemets doubles (") :
- Sur les valeurs des propriétés, les espaces blancs de début et de fin sont coupés.
- Sur les expressions, les lignes d’espace blanc à la fin des expressions sont supprimées.
- Les lignes d’espace blanc sont coupées en lignes vides (aucun espace/onglet).
Gaine
Par défaut, l’API TMDL sur la sérialisation/écriture utilise camelCase, appliquée à :
- Types d’objets
- Mots-clés
- Valeurs d’énumération
Lors de la désérialisation/lecture, l’API TMDL ne respecte pas la casse.
Contenu connexe
Maintenant que vous avez une compréhension de TMDL, veillez à voir bien démarrer avec TMDL pour apprendre à obtenir et déployer une représentation de modèle TMDL d’un modèle Power BI.