Поделиться через


Язык определения табличной модели (TMDL)

применимо: SQL Server 2016 и более поздних версий Служб Analysis Services Azure Analysis Services Fabric/Power BI Premium

Язык определения табличной модели (TMDL) — это синтаксис определения объектной модели для табличных моделей данных на уровне совместимости 1200 или выше.

К ключевым элементам TMDL относятся:

  • Полная совместимость со всеми табличной объектной моделью (TOM). Каждый объект TMDL предоставляет те же свойства, что и TOM.
  • Текстовые и оптимизированные для взаимодействия с человеком и удобства чтения. TMDL использует синтаксис грамматики, аналогичный YAML. Каждый объект TMDL представлен в тексте с минимальными разделителями и использует отступ для демаркации отношений родительского-дочернего элемента.
  • Улучшенный интерфейс редактирования, особенно для свойств с выражениями внедрения из различных типов контента, таких как выражение анализа данных (DAX) и M.
  • Лучше для совместной работы из-за его представления папок, где каждый объект модели имеет отдельное представление файла, что делает его более понятным для системы управления версиями.

Важным аспектом TMDL является использование отступа пробелов для обозначения структуры объекта TOM. В следующем примере показано, как легко представить табличную модель при использовании 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]

Структура папок TMDL

В отличие от TMSL, TMDL использует структуру папок. Структура папок по умолчанию имеет только один уровень вложенных папок, все с файлами TMDL внутри:

  • Культур
  • Перспективы
  • Роли
  • Таблицы

И корневых файлов:

  • база данных
  • модель
  • Отношения
  • Выражения
  • источники данных

Ниже приведен пример папки TMDL:

Папка с представлением TMDL модели

К определениям относятся:

  • Один файл для определения базы данных.
  • Один файл для определения модели.
  • Один файл для всех источников данных в модели.
  • Один файл для всех выражений в модели.
  • Один файл для всех связей в модели.
  • Один файл для каждой лингвистической схемы языка и региональных параметров.
  • Один файл для каждой перспективы.
  • Один файл для каждой роли.
  • Один файл для каждой таблице.
  • Все внутренние свойства метаданных таблиц (столбцы, иерархии, секции,...) хранятся в файле TMDL родительской таблицы.

TMDL API

Аналогичноязыка скриптов табличной модели (TMSL) , существует класс для обработки сериализации TMDL. Для TMDL класс TmdlSerializer в пространстве имен Microsoft.AnalysisServices.Tabular.

Класс TmdlSerializer предоставляет методы для сериализации и десериализации документов TMDL:

Сериализация папок

public static void SerializeDatabaseToFolder (Database database, string path)

  • Получает объект базы данных TOM и выходной путь TMDL.
  • Сериализует базу данных TOM в представление папки TMDL.

Дополнительные о сериализации в папку.

public static Database DeserializeDatabaseFromFolder (string path)

  • Получает полный путь к папке TMDL.
  • Возвращает представление объекта базы данных TOM папки TMDL.

Узнайте больше о десериализации из папок.

Сериализация строк

public static string SerializeObject (MetadataObject object, bool qualifyObject = true)

  • Получает объект TOM и возвращает его текстовое представление TMDL.

Дополнительные о сериализации объекта в строковую.

Сериализация потоковой передачи

Можно сериализовать или десериализировать TMDL в потоки и из потоков, что позволяет преобразовать объект TOM в потоки байтов для хранения, передачи и взаимодействия между платформами. API Stream также позволяет управлять загрузкой документов TMDL и выходными документами TMDL.

Сериализация потоков TMDL обрабатывается классом MetadataSerializationContext.

Дополнительные о сериализации в TMDL с помощью потоков.

Язык TMDL

Объявление объекта

За исключением объекта Server, TMDL предоставляет весь объект toM Database в дереве объектов Microsoft.AnalysisServices.Tabular namespace.

Объект TMDL объявляется путем указания типа объекта TOM, за которым следует его имя. В следующем примере кода каждый тип объекта: model, table, column следует имя объекта.

model Model    
    culture: en-US    

table Sales
    
    measure Sales = SUM(…)
        formatString: $ #,##0

    column 'Customer Key'
        datatype: int64
        sourceColumn: CustomerKey

Объекты, такие как partition или measure, имеют свойства по умолчанию, которые можно назначить после разделителя равенства (=) в той же строке объявления объекта или в следующей строке для многострочный выражения:

table Sales

    partition Sales-Part1 = m
        mode: import
        ...        
    
    measure Sales = SUM(…)
        formatString: $ #,##0

    measure 'Sales (ly)' = 
            var ly = ...
            return ly
        formatString: $ #,##0

Имя объекта TMDL должно быть заключено в одинарные кавычки ('), если он содержит любой из следующих символов:

  • Dot (.)
  • Равно (=)
  • Двоеточие (:)
  • Одна цитата (')
  • Пробелы ( )

Если имя объекта содержит одинарные кавычки (""), используйте две одинарные кавычки для его экранирования.

Свойства объекта

Свойства объекта задаются после объявления объекта или выражения свойства по умолчанию по умолчанию. Значения свойств объекта указываются в качестве разделителя двоеточия (:) . Например:

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"

Следующие правила применяются к значениям свойств:

  • Значение должно находиться в одной строке после двоеточия и не может иметь несколько строк.

  • Текстовые значения свойств

    • Начальные и конечные двойные кавычки являются необязательными и автоматически отрезаны во время сериализации.
    • Должен быть заключен в двойные кавычки ("), если текст содержит конечную или ведущую пробелы.
    • Если значение содержит двойные кавычки, используйте два двойных кавычки для их экранирования (см. свойство displayFolder в приведенном выше примере кода).
  • логические свойства можно задать с помощью стандартного синтаксиса пары "ключ-значение", например с свойством 'isAvailableInMdx' в предыдущем примере. Они также можно задать с помощью сочетания клавиш, где объявляется только имя свойства и true подразумевается. См. пример свойства isHidden в предыдущем примере.

Ссылки на именованные объекты

Некоторые свойства объекта содержат ссылки на другие объекты модели, например:

  • Ссылка на столбец на уровнях иерархии.
  • Ссылка sortByColumn в каждом столбце таблицы.
  • Ссылка на таблицу или столбец или меру в перспективах.

В TMDL ссылки создаются с помощью имени объекта и следуют тем же экранированием и однокавычек (') включающих требования объявления объекта. В следующем примере кода отображаются свойства объектов, которые содержат ссылку на другой объект: column.sortByColumn, level.column, perspectiveMeasure.measure и perspectiveTable.table.


table Product

    column Category
        sortByColumn: 'Category Order'    

 hierarchy 'Product Hierarchy'

  level Category   
   column: Category  
 

perspective Product

 perspectiveTable Product

        perspectiveMeasure '# Products'

Если требуется ссылаться на полное имя, TMDL использует точка нотации для ссылки на объект, например: 'Table 1'.'Column 1'

Дочерние объекты

Дерево объектов TOM содержит дочерние объекты во многих местах и на разных уровнях. Например:

  • Объект модели содержит объекты таблиц, ролей и выражений.
  • Объект таблицы содержит объекты столбца, меры и иерархии.

TMDL не объявляет дочерние коллекции явным образом. Вместо этого все применимые дочерние элементы в области соответствующего родительского элемента неявно составляют элементы соответствующей коллекции. Например, все элементы столбцов в области определенной таблицы становятся элементами коллекции столбцов этой таблицы в TOM, как показано здесь:

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])    

Дочерние объекты не должны быть смежными. Например, можно объявлять столбцы и меры в любом порядке и перемешивание.

Свойства по умолчанию

Некоторые типы объектов имеют свойство по умолчанию, которое больше всего времени обрабатывается как выражения. Свойство по умолчанию — это тип объекта. Если применимо, значение свойства или выражение указывается после разделителя равенства (=) после объявления раздела.

Поддерживаемый синтаксис:

  • Значение указывается в той же строке, что и заголовок раздела.
  • Значение указывается как многострочный выражение после заголовка раздела.

В следующем примере кода мера Sales Amount и секционирование Sales-Partition1 являются одной строкой и Quantity мер является многострочного:

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

Выражения

Существуют свойства объектов, которые, будучи текстовым свойством в TOM, получают специальный анализ в TMDL. Весь текст считывается подробно, так как он может включать специальные символы, такие как кавычки или квадратные скобки в выражениях M или DAX. Выражения могут быть многострочные или однострочные. Если многострочный, они должны находиться в строке сразу после объявления свойства или объекта.

Значение выражения в TMDL указывается следующим разделителем (=), как показано в следующем примере:

table Table1

    partition 'partition 1' = m
        mode: import
        source =
            let
            ...
            in
                finalStep
    
    measure Measure1 = SUM(...)

    measure Measure2 =
            var result = SUMX ( 
                ...
            )
            return result
        formatString: $ #,##0

Следующие специальные правила применяются к выражениям:

  • Выражения с несколькими строками должны быть отступлены на один уровень глубже к свойствам родительского объекта, и все выражение должно находиться в пределах этого отступа.
  • Все внешние пробелы отступов удаляются за пределы отступа родительского объекта.
  • Вертикальные пробелы (пустые строки без пробелов) разрешены и считаются частью выражения.
  • Удаляются конечные пустые строки и пробелы.
  • Чтобы применить другую отступ или сохранить конечные пустые строки или пробелы, используйте три отступа (```) включающиеся.
  • По умолчанию сериализатор TMDL будет заключаться с обратными знаками, если значение выражения содержит что-либо, что может привести к внесению изменений в круглые пути (например, конечные пробелы, пустые строки с пробелами).

Выражения, заключенные с тремя обратными знаками (```) считываются подробно, включая отступы, пустые строки и пробелы. Разделитель должен применяться сразу после знака равенства (=) и строки, следующей за выражением, и не может иметь ничего после него, как показано в следующем примере:

table Table1

    partition partition1 = m
        mode: import
        source = ```
            let
            ...
            in
                finalStep

            ```

    measure Measure1 = ```
                var myVar = Today()
                …
                return result
            ```

Использование трех разделителей (```) является необязательным и требуется только в уникальных ситуациях. В большинстве случаев использование правильного отступа и объявления объектов обеспечивает правильный анализ любого выражения, добавляемого в свойство.

Если выражение заключено в обратные очки, применяются следующие правила:

  • Все между тремя отступами (```) считается частью многоблокового выражения и правил отступа TMDL не применяются. Конечный разделитель определяет отступ в выражении.
  • Относительная отступность в выражении сохраняется. Конечный разделитель (```) определяет левую границу выражения (см. "Measure1" в предыдущем примере).

Следующие свойства рассматриваются как выражения:

Тип объекта Свойство Язык выражений
Измерять Выражение ДАКС
MPartitionSource Выражение M
CalculatedPartitionSource Выражение ДАКС
QueryPartitionSource Запрос NativeQuery
CalculationItem Выражение ДАКС
BasicRefreshPolicy SourceExpression, PollingExpression M
Ключевой показатель эффективности StatusExpression, TargetExpression, TrendExpression ДАКС
Лингвистические метаданные Содержание XML или JSON
JsonExtendedProperty Ценность Json
FormatStringDefintion Выражение ДАКС
DataCoverageDefinition Выражение ДАКС
CalculationGroupExpression Выражение ДАКС
NamedExpression Выражение ДАКС
DetailRowsDefinition Выражение ДАКС
TablePermission FilterExpression ДАКС
CalculatedColumn Выражение ДАКС

Свойства по умолчанию по типу объекта

В следующей таблице показаны язык свойств и выражений по типу объекта по умолчанию:

Тип объекта Свойство по умолчанию Язык выражений
Измерять Выражение ДАКС
CalculatedColumn Выражение ДАКС
CalculationItem Выражение ДАКС
FormatStringDefinition Выражение ДАКС
DetailRowsDefinition Выражение ДАКС
ВычислениеExpression Выражение ДАКС
DataCoverageDefinition Выражение ДАКС
TablePermission FilterExpression ДАКС
ColumnPermission MetadataPermission Перечисление метаданныхPermission
NamedExpression Выражение M
MPartitionSource Выражение M
CalculatedPartitionSource Выражение ДАКС
JsonExtendedProperty Ценность Json
Аннотация Ценность СМС
StringExtendedProperty Ценность СМС
DataSource Тип DataSourceType Enum
Раздел SourceType PartitionSourceType Enum
ChangedProperty Свойство текст свойств
ExternalModelRoleMember MemberType RoleMemberType Enum
Любое пользовательское свойство JSON (например, DataAccessOptions) Документ JSON Json
Лингвистические метаданные Содержание Json

Описания

TMDL предоставляет поддержку первого класса для описания. В целях документации по модели рекомендуется предоставить описания для каждого объекта TOM. TMDL обрабатывает описания как специальное свойство с явной поддержкой синтаксиса. После примеров из многих других языков описания указываются поверх каждого объявления объекта с помощью синтаксиса тройной косой черты (///).

Пробелы не допускаются между концем блока описания и маркером типа объекта.

Описания могут быть разделены по нескольким строкам. Сериализатор TMDL разбивает описания объектов на несколько строк, чтобы обеспечить максимальную длину создаваемых строк документов. Максимальная длина по умолчанию составляет 80 символов.

/// Table Description
table Sales

    /// This is the Measure Description
    /// One more line
    measure 'Sales Amount'' = SUM(...)
        formatString: #,##0

Частичное объявление

TMDL не принудительно объявляет объект в том же документе. Однако это похоже на частичные классы C# C#, где можно разделить определение объекта между несколькими файлами. Например, можно объявить определение таблицы в файле [table].tmdl, а затем получить все меры из всех таблиц, определенных в одном файле [меры].tmdl, как показано ниже:

table Sales

    measure 'Sales Amount' = SUM(…)
        formatString: $ #,##0

table Product

    measure CountOfProduct = COUNTROWS(…)

Чтобы избежать ошибки синтаксического анализа, то же свойство нельзя объявить дважды. Например, объявление двух мер с одинаковым именем для одной таблицы в двух разных документах TMDL приводит к ошибке.

Ссылки на объекты

Вы можете ссылаться на другой объект TMDL с помощью ключевого слова ref, за которым следует тип объекта и имя.

Например, если вы сериализуете объект Column с помощью API сериализации строк, результат будет следующим:

ref table Table1
	column Column1
		datatype: int64
		sourceColumn: Column1

Детерминированное упорядочивание коллекции

Ключевое слово ref также используется для определения и сохранения порядка коллекции в <> циклического обхода TMDL toM. Особенно важно избежать диффа системы управления версиями в объектах TMDL, сериализованных в отдельные файлы: таблицы, роли, культуры и перспективы. Ключевое слово ref используется в файле TMDL родительского объекта для объявления порядка элементов из 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'

Применяются следующие правила:

  • Во время десериализации TMDL:
    • Объекты, на которые ссылается TMDL, но с отсутствующим файлом TMDL, игнорируются.
    • Объекты, на которые не ссылается, но с существующим файлом TMDL, добавляются в конец коллекции.
  • Во время сериализации TMDL:
    • Все объекты коллекции в TOM ссылаются с помощью ключевого слова ref.
    • Коллекции только с одним элементом не выдают ссылку.
    • Пустые строки не создаются между ref, если один и тот же тип объекта.

Разделители значений свойств

Для назначения значения свойства можно назначить только два разделителя или символа:

  • Равно (=)

    • Используется в объявлении объектов с свойством по умолчанию (многострочный и однострочный)
    • Используется для каждого свойства выражения , например partition.expression
  • Двоеточие (:)

    • Используется для каждого значения свойства, отличного от выражения . Включая свойства, которые содержат ссылки на модель.

Отступ

TMDL использует строгие правила отступа пробелов для обозначения структуры иерархии TOM. Документ TMDL использует одно вкладку по умолчанию отступа.

Каждый объект может иметь три уровня отступа:

  • Уровень 1. Объявление объекта
    • Уровень 2. Свойства объекта
      • Уровень 3. Многострочный выражения свойства объекта

В документе TMDL отступ применяется в следующих случаях:

  • Между заголовком раздела объекта и свойствами объекта (таблица —> свойства).

    table Sales
        isHidden
        lineageTag: 9a48bea0-e5fb-40fa-9e81-f61288e31a02
    
  • Между объектом и дочерними объектами (таблица —> меры).

    table Sales
    
        measure 'Sales Amount' = SUMX(...)
    
        measure 'Total Quantity' = SUM(...)
    
  • Между объектом и его многострочный выражений (таблица —> мера —> выражение).

    table Sales
    
        measure 'Sales Amount' = 
                var result = SUMX(...)
                return result
            formatString: $ #,##0
    
  • Многострочный выражения должны быть отступами одного уровня глубже, чем свойства объекта, и все выражение должно находиться в пределах этого уровня отступа (см. выражения).

База данных и прямые дочерние объекты модели не должны быть отступлены, так как они неявно предполагаются вложенными в корневую модель или базу данных:

  • модель
  • Таблицы
  • общие выражения
  • Роли
  • Культур
  • Перспективы
  • Отношения
  • источники данных
  • Группы запросов
  • Заметки уровня модели
  • Расширенные свойства уровня модели

Не следуя этим правилам отступа, возникает ошибка синтаксического анализа.

Пробелы

TMDL по умолчанию применяет следующие правила к пробелам в значениях свойств и выражений, если они не заключены в обратные (```) или двойные кавычки ("):

  • Для значений свойств обрезаются начальные и конечные пробелы.
  • В выражениях строки пробелов в конце выражений удаляются.
  • Строки пробелов обрезаются до пустых строк (пробелы и вкладки).

Оболочка

По умолчанию API TMDL для сериализации и записи использует верблюдье, примененный к:

  • Типы объектов
  • Ключевые слова
  • Значения перечисления

При десериализации и чтении API TMDL не учитывает регистр.

Теперь, когда у вас есть представление о TMDL, убедитесь, что приступая к работе с TMDL, чтобы узнать, как получить и развернуть представление модели TMDL в семантической модели Power BI.