次の方法で共有


TMDL の概要

適用対象: Azure Analysis Services Fabric/Power BI Premium SQL Server 2016 以降の Analysis Services

この記事を開始する前に、テーブル モデル定義言語 (TMDL) の概要で説明されている概念を十分に理解してください。

TMDL を調べる最も簡単な方法は、Analysis Services Management Objects (AMO) Nuget パッケージ を参照し、TMDL API メソッドを使用して TMDL との間でシリアル化および逆シリアル化することです。

Nuget パッケージを取得する

TMDL モデル表現を取得する

次のコード例は、Power BI Premium ワークスペースでセマンティック モデルの TMDL モデル表現を取得する方法を示しています。

var workspaceXmla = " <Workspace XMLA address>";
var datasetName = "<dataset name>";
var outputPath = System.Environment.CurrentDirectory;

using (var server = new Server())
{
    server.Connect(workspaceXmla);

    var database = server.Databases.GetByName(datasetName);

    var destinationFolder = $"{outputPath}\\{database.Name}-tmdl";

    TmdlSerializer.SerializeDatabaseToFolder(database.Model, destinationFolder);

}

出力は、次のように、モデルの TMDL 表現を含むフォルダーです。

モデル の TMDL 表現を持つ フォルダー

フォルダーにシリアル化した後、テキスト エディターを使用して TMDL ファイルを編集します。 たとえば、Visual Studio Code を使用すると、[Sales Amount (Computers)] 新しいメジャーを追加

/// 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

エクスペリエンスを向上するために、Visual Studio Code TMDL 言語拡張機能インストールできます。

TMDL モデル表現をデプロイする

次のコード例は、モデルの TMDL モデル表現を Power BI Premium ワークスペースにデプロイする方法を示しています。

var xmlaServer = "<Workspace XMLA address>";

var tmdlFolderPath = $"{System.Environment.CurrentDirectory}\\Contoso-tmdl";

var model = TmdlSerializer.DeserializeDatabaseFromFolder(tmdlFolderPath);            

using (var server = new Server())
{
    server.Connect(xmlaServer);

    using (var remoteDatabase = server.Databases[model.Database.ID])
    {
        model.CopyTo(remoteDatabase.Model);

        remoteDatabase.Model.SaveChanges();
    }               
}

実行すると、新しいメジャーがモデルにデプロイされます。

データセット の Sales Amount (Computers) メジャー

TMDL シリアル化エラーの処理

TMDL シリアル化メソッドでエラーが検出されると、ArgumentExceptionInvalidOperationExceptionなど、いくつかの一般的な .NET 例外をスローするだけでなく、TMDL 固有の例外も返されます。

  • TMDL テキストが有効な構文でない場合は、TmdlFormatException がスローされます。 たとえば、キーワードやインデントが無効です。

  • TMDL テキストが有効であるが、TOM メタデータ ロジックに違反している場合、TmdlSerializationException がスローされます。 たとえば、値の型が想定される型と一致しません。

例外の詳細に加えて、次のものが含まれます。

  • document path: エラーが発生した TMDL ファイルへのパス。
  • line number: エラーのある行番号。
  • line text: エラーのある行テキスト。

TmdlFormatExceptionを処理するコード例:

try
{
    var tmdlPath = "<TMDL Folder Path>";

    var model = TmdlSerializer.DeserializeDatabaseFromFolder(tmdlPath);
}
catch (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 = 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

ストリームのシリアル化

次のコード例は、セマンティック モデルを 1 つのテキスト変数にシリアル化する方法を示しています。

var output = new StringBuilder();

foreach (MetadataDocument document in model.ToTmdl())
{
    using (TextWriter writer = new StringWriter(output))
    {
        document.WriteTo(writer);
    }
}

Console.WriteLine(output.ToString());

次のコード例は、ロールを除き、TMDL から逆シリアル化する方法を示しています。

var context = 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();