TMDL(테이블 형식 모델 정의 언어)

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

중요

TMDL(테이블 형식 모델 정의 언어)은 현재 미리 보기로 제공됩니다. 미리 보기 단계에서는 기능 및 설명서가 변경될 수 있습니다.

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 파일이 있습니다.

  • cultures
  • 큐브 뷰
  • 역할
  • 테이블

에 대한 루트 파일 :

  • 데이터베이스
  • model
  • relationships
  • datasources

TMDL 폴더의 예는 다음과 같습니다.

모델의 TMDL 표현이 있는 폴더

정의에는 다음이 포함됩니다.

  • 데이터베이스 정의용 파일 1개.
  • 모델 정의용 파일 1개.
  • 모델의 모든 데이터 원본에 대한 하나의 파일입니다.
  • 모델의 모든 식에 대한 하나의 파일입니다.
  • 모델의 모든 관계에 대한 하나의 파일입니다.
  • 문화권 언어 스키마에 대한 하나의 파일입니다.
  • 큐브 뷰에 대해 하나의 파일입니다.
  • 역할에 대해 하나의 파일입니다.
  • 테이블에 대해 하나의 파일입니다.
  • 테이블의 모든 내부 메타데이터 속성(열, 계층, 파티션,...) 메타데이터는 부모 테이블 TMDL 파일에 있습니다.

TMDL API

TMSL(테이블 형식 모델 스크립팅 언어)과 마찬가지로 TMDL Serialization을 처리하는 클래스가 있습니다. TMDL의 경우 클래스는 Microsoft.AnalysisServices.Tabular 네임스페이스 아래의 TmdlSerializer입니다.

TmdlSerializer 클래스는 TMDL 문서를 직렬화하고 역직렬화하는 메서드를 노출합니다.

폴더 직렬화

public static void SerializeDatabaseToFolder (Database database, string path)

  • TOM 데이터베이스 개체 및 TMDL 출력 경로를 받습니다.
  • TOM 데이터베이스를 TMDL 폴더 표현으로 직렬화합니다.

폴더로 직렬화하는 방법에 대해 자세히 알아봅니다.

public static Database DeserializeDatabaseFromFolder (string path)

  • TMDL 폴더에 대한 전체 경로를 받습니다.
  • TMDL 폴더의 TOM 데이터베이스 개체 표현을 반환합니다.

폴더에서 역직렬화하는 방법에 대해 자세히 알아봅니다.

문자열 Serialization

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

  • TOM 개체를 수신하고 해당 TMDL 텍스트 표현을 반환합니다.

개체를 문자열로 serialize하는 방법에 대해 자세히 알아봅니다.

스트림 Serialization

TMDL을 스트림 간에 직렬화/역직렬화하여 플랫폼 간 스토리지, 전송 및 상호 운용성을 위해 TOM 개체를 바이트 스트림으로 변환할 수 있습니다. Stream API를 사용하면 로드되는 TMDL 문서와 출력되는 TMDL 문서를 제어할 수도 있습니다.

TMDL 스트림 serialization은 MetadataSerializationContext 클래스에 의해 처리됩니다.

스트림을 사용하여 TMDL로 직렬화하는 방법에 대해 자세히 알아봅니다.

TMDL 언어

개체 선언

Server 개체를 제외하고 TMDL은 Microsoft.AnalysisServices.Tabular 네임스페이스의 전체 TOM Database 개체 트리를 노출합니다.

TMDL 개체는 TOM 개체 형식과 그 이름을 지정하여 선언됩니다. 다음 코드 예제에서 각 개체 형식은 model, , tablecolumn 뒤에 개체 이름이 입니다.

model Model    
    culture: en-US    

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

    column 'Customer Key'
        datatype: int64
        sourceColumn: CustomerKey

또는 measure 와 같은 partition 개체에는 개체 선언의 동일한 줄에 있는 등호(=) 구분 기호 뒤에 할당하거나 여러 줄 에 대해 다음 줄에 할당할 수 있는 기본 속성이 있습니다.

table Sales

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

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

다음 문자가 포함된 경우 TMDL 개체 이름을 작은따옴표(')로 묶어야 합니다.

  • 점(.)
  • Equals(=)
  • 콜론(:)
  • 작은따옴표(')
  • 공백( )

개체 이름에 작은따옴표(') 포함된 경우 두 개의 작은따옴표를 사용하여 이스케이프합니다.

개체 속성

개체 속성은 개체 선언 또는 개체 기본 속성 다중 줄 식 다음에 지정됩니다. 개체 속성 값은 콜론(:) 구분 기호 다음에 지정됩니다. 예를 들면 다음과 같습니다.

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"

속성 값에는 다음 규칙이 적용됩니다.

  • 값은 콜론 다음의 동일한 줄에 있어야 하며 여러 줄을 가질 수 없습니다.

  • 텍스트 속성 값

    • 선행 및 후행 큰따옴표는 선택 사항이며 serialization 중에 자동으로 제거됩니다.
    • 텍스트에 후행 공백 또는 선행 공백이 포함된 경우 큰따옴표(")로 묶어야 합니다.
    • 큰따옴표로 묶인 경우 값에 큰따옴표가 포함된 경우 두 개의 큰따옴표를 사용하여 이스케이프합니다(위의 코드 예제에서 속성 참조 displayFolder ).
  • 부울 속성은 이전 예제의 속성과 'isAvailableInMdx' 마찬가지로 표준 키/값 쌍 구문을 사용하여 설정할 수 있습니다. 속성 이름만 선언되고 true 암시되는 바로 가기 구문을 사용하여 설정할 수도 있습니다. 예를 들어 이전 예제의 'isHidden' 속성을 참조하세요.

명명된 개체 참조

일부 개체 속성은 다른 모델 개체에 대한 참조를 보유합니다. 예를 들면 다음과 같습니다.

  • 계층 수준의 열 참조입니다.
  • 각 테이블 열의 sortByColumn 참조입니다.
  • 큐브 뷰의 테이블/열/측정값 참조입니다.

TMDL에서 참조는 개체 이름을 사용하여 만들어지고 개체 선언의 동일한 이스케이프 및 작은따옴표(') 바깥쪽 요구 사항을 따릅니다. 다음 코드 예제에서는 , 및 다른 개체에 대한 참조를 포함하는 개체 column.sortByColumnlevel.columnperspectiveMeasure.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은 자식 컬렉션을 명시적으로 선언하지 않습니다. 대신 해당 부모의 scope 내에서 적용 가능한 모든 자식 요소가 해당 컬렉션의 요소를 암시적으로 구성합니다. 예를 들어 특정 테이블의 scope 내의 모든 열 요소는 다음과 같이 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 serializer는 식 값에 왕복에 대한 수정을 유발할 수 있는 항목(예: 후행 공백, 공백이 있는 빈 줄)이 포함된 경우 백틱으로 묶습니다.

세 개의 백틱(```)으로 묶인 식은 들여쓰기, 빈 줄 및 공백을 포함하여 축자에서 읽습니다. 구분 기호는 등호(=)와 식 다음 줄 바로 뒤에 적용해야 하며 다음 예제와 같이 그 뒤에 아무 것도 있을 수 없습니다.

table Table1

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

            ```

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

세 개의 백틱(```) 구분 기호를 사용하는 것은 선택 사항이며 고유한 상황에서만 필요합니다. 대부분의 경우 올바른 들여쓰기 및 개체 선언을 사용하면 속성에 추가하는 식의 올바른 구문 분석이 보장됩니다.

식이 백틱 내에 묶이면 다음 규칙이 적용됩니다.

  • 세 개의 백틱(```) 사이의 모든 항목은 다중 블록 식의 일부로 간주되며 TMDL 들여쓰기 규칙은 적용되지 않습니다. 끝 구분 기호는 식 내의 들여쓰기를 결정합니다.
  • 식 내의 상대 들여쓰기는 유지됩니다. 끝 구분 기호(```)는 식 왼쪽 경계를 결정합니다(이전 예제의 'Measure1'참조).

다음 속성은 식으로 처리됩니다.

개체 유형 속성 식 언어
측정값 DAX
MPartitionSource M
CalculatedPartitionSource DAX
QueryPartitionSource 쿼리 NativeQuery
CalculationItem DAX
BasicRefreshPolicy SourceExpression, PollingExpression M
KPI StatusExpression, TargetExpression, TrendExpression DAX
LinguisticMetadata 콘텐츠 XML 또는 Json
JsonExtendedProperty Json
FormatStringDefintion DAX
DataCoverageDefinition DAX
CalculationGroupExpression DAX
NamedExpression DAX
DetailRowsDefinition DAX
TablePermission FilterExpression DAX
CalculatedColumn DAX

개체 유형별 기본 속성

다음 표에서는 개체 유형별 기본 속성 및 식 언어를 보여줍니다.

개체 유형 기본 속성 식 언어
측정값 DAX
CalculatedColumn DAX
CalculationItem DAX
FormatStringDefinition DAX
DetailRowsDefinition DAX
CalculationExpression DAX
DataCoverageDefinition DAX
TablePermission FilterExpression DAX
ColumnPermission MetadataPermission MetadataPermission 열거형
NamedExpression M
MPartitionSource M
CalculatedPartitionSource DAX
JsonExtendedProperty Json
Annotation 텍스트
StringExtendedProperty 텍스트
DataSource 형식 DataSourceType 열거형
파티션 SourceType PartitionSourceType 열거형
ChangedProperty 속성 속성 텍스트
ExternalModelRoleMember MemberType RoleMemberType 열거형
모든 사용자 지정 JSON 속성(예: DataAccessOptions) JSON 문서 Json
LinguisticMetadata 콘텐츠 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# 부분 클래스 와 비슷합니다. 예를 들어 다음과 같이 [table].tmdl 파일에서 테이블 정의를 선언한 다음 모든 테이블의 모든 측정값을 단일 [measures].tmdl 파일에 정의할 수 있습니다.

table Sales

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

table Product

    measure CountOfProduct = COUNTROWS(…)

구문 분석 오류를 방지하기 위해 동일한 속성을 두 번 선언할 수 없습니다. 예를 들어 두 개의 서로 다른 TMDL 문서에서 동일한 테이블에 대해 이름이 같은 두 측정값을 선언하면 오류가 발생합니다.

개체 참조

ref 키워드(keyword) 뒤에 개체 유형 및 이름을 사용하여 다른 TMDL 개체를 참조할 수 있습니다.

예를 들어 문자열 serialization API를 사용하여 Column 개체를 직렬화하는 경우 결과는 다음과 같습니다.

ref table Table1
	column Column1
		datatype: int64
		sourceColumn: Column1

결정적 컬렉션 순서 지정

ref 키워드(keyword) TOM <> TMDL 왕복에서 컬렉션 순서를 정의하고 유지하는 데도 사용됩니다. 테이블, 역할, 문화권 및 큐브 뷰와 같은 개별 파일로 직렬화되는 TMDL 개체에서 소스 제어 diff 방지하는 것이 특히 중요합니다. ref 키워드(keyword) TOM에서 정렬하는 항목을 선언하기 위해 부모 개체 TMDL 파일에서 사용됩니다.


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 Serialization 중:
    • TOM의 모든 컬렉션 개체는 ref 키워드(keyword) 사용하여 참조됩니다.
    • 항목이 하나만 있는 컬렉션은 ref를 내보내지 않습니다.
    • 동일한 개체 형식인 경우 ref의 사이에 빈 줄이 내보내지지 않습니다.

속성 값 구분 기호

속성 값을 할당하는 데는 두 개의 구분 기호/기호만 있습니다.

  • Equals(=)

    • 기본 속성(다중 및 한 줄)을 사용하여 개체 선언에서 사용됨
    • 모든 식 속성(예: 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
    
  • 여러 줄 식은 개체 속성보다 한 수준 더 깊이 들여쓰기해야 하며 전체 식은 해당 들여쓰기 수준 내에 있어야 합니다( 참조).

Model의 데이터베이스 및 직접 자식 개체는 루트 모델 또는 데이터베이스 아래에 중첩된 것으로 암시적으로 가정되므로 들여쓰기할 필요가 없습니다.

  • model
  • 테이블
  • 공유 식
  • 역할
  • cultures
  • 큐브 뷰
  • relationships
  • 데이터 원본
  • 그룹 쿼리
  • 모델 수준 주석
  • 모델 수준 확장 속성

이러한 들여찾기 규칙을 따르지 않을 경우 구문 분석 오류가 발생합니다.

공백

기본적으로 TMDL은 백틱() 또는 큰따옴표(```") 내에 묶이지 않는 경우 속성 및 식 값 내의 공백에 다음 규칙을 적용합니다.

  • 속성 값에서 선행 및 후행 공백이 잘립니다.
  • 식의 경우 식 끝에 있는 공백 줄이 삭제됩니다.
  • 공백 선은 빈 선(공백/탭 없음)으로 잘립니다.

대/소문자 구분

serialize/write 사용 camelCase의 기본 TMDL API는 다음 항목에 적용됩니다.

  • 개체 유형
  • 키워드
  • 열거형 값

역직렬화/읽기에서 TMDL API는 대/소문자를 구분하지 않습니다.

고려 사항 및 제한 사항

이제 TMDL을 이해했으므로 TMDL 시작을 참조하여 Power BI 의미 체계 모델의 TMDL 모델 표현을 가져와 배포하는 방법을 알아보세요.