다음을 통해 공유


TMDL 시작

적용 대상: SQL Server 2016 이상 Analysis Services Azure Analysis Services Fabric/Power BI Premium

이 문서를 시작하기 전에 TMDL(테이블 형식 모델 정의 언어) 개요설명된 개념을 철저히 이해해야 합니다.

TMDL을 탐색하는 가장 쉬운 방법은 AMO(Analysis Services Management Objects) 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 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 표현이 있는 폴더

폴더로 serialization한 후 텍스트 편집기를 사용하여 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

더 나은 환경을 위해 visual Studio Code TMDL 언어 확장설치할 수 있습니다.

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 serialization 오류 처리

TMDL serialization 메서드에서 오류가 검색되면 ArgumentExceptionInvalidOperationException같은 몇 가지 일반적인 .NET 예외를 throw하는 것 외에 TMDL 관련 예외도 반환됩니다.

  • TMDL 텍스트가 유효한 구문이 아닌 경우 TmdlFormatException throw됩니다. 예를 들어 잘못된 키워드 또는 들여쓰기입니다.

  • TMDL 텍스트가 유효하지만 TOM 메타데이터 논리를 위반하면 TmdlSerializationException throw됩니다. 예를 들어 값 형식이 예상 형식과 일치하지 않습니다.

예외 세부 정보 외에도 다음이 포함됩니다.

  • 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;
}    

개체 텍스트 serialization

다음 코드 예제에서는 열을 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

스트림 serialization

다음 코드 예제에서는 의미 체계 모델을 단일 텍스트 변수로 직렬화하는 방법을 보여줍니다.

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