적용 대상:
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 메서드에서 오류가 검색되면 ArgumentException 및 InvalidOperationException같은 몇 가지 일반적인 .NET 예외를 throw하는 것 외에 TMDL 관련 예외도 반환됩니다.
TMDL 텍스트가 유효한 구문이 아닌 경우
TmdlFormatExceptionthrow됩니다. 예를 들어 잘못된 키워드 또는 들여쓰기입니다.TMDL 텍스트가 유효하지만 TOM 메타데이터 논리를 위반하면
TmdlSerializationExceptionthrow됩니다. 예를 들어 값 형식이 예상 형식과 일치하지 않습니다.
예외 세부 정보 외에도 다음이 포함됩니다.
-
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();