Partager via


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 :

Dossier avec une représentation TMDL d’un modèle

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é et true 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 suivi du type et du nom de l’objet.

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.

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 (:)

    • Utilisé pour chaque valeur de propriété non-expression . Y compris les propriétés qui contiennent des références de modèle.

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

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.

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.