Начало работы с TMDL
применимо: SQL Server 2016 и более поздних версий Служб Analysis Services Azure Analysis Services Fabric/Power BI Premium
Прежде чем приступить к работе с этой статьей, необходимо тщательно понять основные понятия, описанные в обзор языка определения табличной модели (TMDL).
Самый простой способ изучения TMDL — ссылаться на объекты управления службами Analysis Services (AMO) пакет Nuget и использовать методы API TMDL для сериализации и десериализации из TMDL.
Получение представления модели TMDL
В следующем примере кода показано, как получить представление модели TMDL в семантической модели в рабочей области Power BI Premium:
var workspaceXmla = " <Workspace XMLA address>";
var datasetName = "<dataset name>";
var outputPath = System.Environment.CurrentDirectory;
using (var server = new Microsoft.AnalysisServices.Tabular.Server())
{
server.Connect(workspaceXmla);
var database = server.Databases.GetByName(datasetName);
var destinationFolder = $"{outputPath}\\{database.Name}-tmdl";
Microsoft.AnalysisServices.Tabular.TmdlSerializer.SerializeDatabaseToFolder(database.Model, destinationFolder);
}
Выходные данные — это папка с представлением TMDL модели, как показано ниже.
Папка
После сериализации в папку используйте текстовый редактор для редактирования файлов TMDL. Например, с помощью Visual Studio Code можно добавить новую меру, [объем продаж (компьютеры)]:
/// Sales data for year over year analysis
table Sales
partition 'Sales-Part1' = m
mode: Import
source =
let
…
in
#"Filtered Rows1"
measure 'Sales Amount' = SUMX('Sales', [Quantity] * [Net Price])
formatString: $ #,##0
measure 'Sales Amount (Computers)' = CALCULATE([Sales Amount], 'Product'[Category] = "Computers")
formatString: $ #,##0
Чтобы лучше установить расширения языка TMDL Visual Studio Code.
Развертывание представления модели TMDL
В следующем примере кода показано, как развернуть представление модели TMDL в рабочей области Power BI Premium:
var xmlaServer = "<Workspace XMLA address>";
var tmdlFolderPath = $"{System.Environment.CurrentDirectory}\\Contoso-tmdl";
var model = Microsoft.AnalysisServices.Tabular.TmdlSerializer.DeserializeModelFromFolder(tmdlFolderPath);
using (var server = new Microsoft.AnalysisServices.Tabular.Server())
{
server.Connect(xmlaServer);
using (var remoteDatabase = server.Databases[model.Database.ID])
{
model.CopyTo(remoteDatabase.Model);
remoteDatabase.Model.SaveChanges();
}
}
При выполнении новая мера развертывается в модели.
Обработка ошибок сериализации TMDL
При обнаружении ошибки в методах сериализации TMDL, помимо создания нескольких распространенных исключений .NET, таких как ArgumentException
и InvalidOperationException
, также возвращаются исключения, относящиеся к TMDL.
TmdlFormatException
возникает, если текст TMDL не является допустимым синтаксисом. Например, недопустимое ключевое слово или отступ.TmdlSerializationException
возникает, если текст TMDL является допустимым, но нарушает логику метаданных TOM. Например, тип значения не соответствует ожидаемому типу.
Помимо сведений об исключении, включено следующее:
-
document path
: путь к файлу TMDL с ошибками. -
line number
: номер строки с ошибками. -
line text
: текст строки с ошибками.
Пример кода, обрабатывая TmdlFormatException
:
try
{
var tmdlPath = "<TMDL Folder Path>";
var model = Microsoft.AnalysisServices.Tabular.TmdlSerializer.DeserializeDatabaseFromFolder(tmdlPath);
}
catch (Microsoft.AnalysisServices.Tabular.Tmdl.TmdlFormatException ex)
{
Console.WriteLine($"Error on Deserializing TMDL '{ex.Message}', document path: '{ex.Document}' line number: '{ex.Line}', line text: '{ex.LineText}'");
throw;
}
Сериализация текста объекта
В следующем примере кода показано, как сериализовать столбец в TMDL:
var output = Microsoft.AnalysisServices.Tabular.TmdlSerializer.SerializeObject(model.Tables["Product"].Columns["ProductKey"], qualifyObject: true);
Console.WriteLine(output);
Выпуск:
ref table Product
column ProductKey
dataType: int64
isKey
formatString: 0
isAvailableInMdx: false
lineageTag: 4184d53e-cd2d-4cbe-b8cb-04c72a750bc4
summarizeBy: none
sourceColumn: ProductKey
annotation SummarizationSetBy = Automatic
Потоковая сериализация
В следующем примере кода показано, как сериализовать семантику модели в одну текстовую переменную:
var output = new StringBuilder();
foreach (Microsoft.AnalysisServices.Tabular.Serialization.MetadataDocument document in model.ToTmdl())
{
using (TextWriter writer = new StringWriter(output))
{
document.WriteTo(writer);
}
}
Console.WriteLine(output.ToString());
В следующем примере кода показано, как десериализировать из TMDL, за исключением ролей:
var context = Microsoft.AnalysisServices.Tabular.Serialization.MetadataSerializationContext.Create(MetadataSerializationStyle.Tmdl);
var files = Directory.GetFiles("[TMDL Directory Path]", "*.tmdl", SearchOption.AllDirectories);
foreach (var file in files)
{
if (file.Contains("/roles/"))
continue;
using (TextReader reader = File.OpenText(file))
{
context.ReadFromDocument(file, reader);
}
}
var model = context.ToModel();