TMDL(테이블 형식 모델 정의 언어)
적용 대상: SQL Server 2016 이상 Analysis Services Azure Analysis Services Fabric/Power BI Premium
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 폴더의 예는 다음과 같습니다.
모델 TMDL 표현이 있는
정의에는 다음이 포함됩니다.
- 데이터베이스 정의용 파일 1개.
- 모델 정의용 파일 1개.
- 모델의 모든 데이터 원본을
하나의 파일입니다. - 모델의 모든 식을
하나의 파일입니다. - 모델의 모든 관계를
하나의 파일입니다. - 각 문화권 언어 스키마를
하나의 파일입니다. - 각 큐브 뷰를
하나의 파일입니다. - 각 역할을
하나의 파일입니다. - 각 테이블을
하나의 파일입니다. - 테이블의 모든 내부 메타데이터 속성(열, 계층, 파티션,...) 메타데이터는 부모 테이블 TMDL 파일에 있습니다.
TMDL API
TMSL(테이블 형식 모델 스크립팅 언어)마찬가지로 TMDL Serialization을 처리하는 클래스가 있습니다. TMDL의 경우 클래스는
TmdlSerializer 클래스는 TMDL 문서를 직렬화하고 역직렬화하는 메서드를 노출합니다.
폴더 Serialization
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하는 방법에 대한 자세한
Stream Serialization
TMDL을 스트림 간 직렬화/역직렬화하여 TOM 개체를 플랫폼 간 스토리지, 전송 및 상호 운용성을 위해 바이트 스트림으로 변환할 수 있습니다. 또한 Stream API를 사용하면 로드되는 TMDL 문서와 출력되는 TMDL 문서를 제어할 수 있습니다.
TMDL Stream serialization은 MetadataSerializationContext 클래스에서 처리됩니다.
스트림사용하여 TMDL에서 직렬화하는 방법에 대한 자세한
TMDL 언어
개체 선언
서버 개체를 제외하고 TMDL은 Microsoft.AnalysisServices.Tabular 네임스페이스
TMDL 개체는 TOM 개체 형식과 그 이름을 지정하여 선언됩니다. 다음 코드 예제에서 각 개체 유형은 model
, table
, column
뒤에 개체 이름이 잇습니다.
model Model
culture: en-US
table Sales
measure Sales = SUM(…)
formatString: $ #,##0
column 'Customer Key'
datatype: int64
sourceColumn: CustomerKey
partition
또는 measure
같은 개체에는 개체 선언의 동일한 줄에 있는 등호(=) 구분 기호 뒤에 할당하거나 여러 줄 식다음 줄에 할당할 수 있는 기본 속성 있습니다.
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.sortByColumn
, level.column
, perspectiveMeasure.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은 자식 컬렉션을 명시적으로 선언하지 않습니다. 대신 해당 부모 범위 내의 적용 가능한 모든 자식 요소는 해당 컬렉션의 요소를 암시적으로 구성합니다. 예를 들어 특정 테이블 범위 내의 모든 열 요소는 다음과 같이 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 |
주석 | 값 | 문자 메시지 |
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은 동일한 문서에서 개체 선언을 강제로 적용하지 않습니다. 그러나 여러 파일 간에 개체 정의를 분할할 수 있는
table Sales
measure 'Sales Amount' = SUM(…)
formatString: $ #,##0
table Product
measure CountOfProduct = COUNTROWS(…)
구문 분석 오류를 방지하기 위해 동일한 속성을 두 번 선언할 수 없습니다. 예를 들어 두 개의 서로 다른 TMDL 문서에서 동일한 테이블에 대해 이름이 같은 두 측정값을 선언하면 오류가 발생합니다.
개체 참조
ref 키워드와 개체 형식 및 이름을 사용하여 다른 TMDL 개체를 참조할 수 있습니다.
예를 들어 문자열 serialization API를 사용하여 Column 개체를 직렬화하는 경우 결과는 다음과 같습니다.
ref table Table1
column Column1
datatype: int64
sourceColumn: Column1
결정적 컬렉션 순서 지정
ref 키워드는 TOM <> TMDL 왕복에서 컬렉션 순서를 정의하고 유지하는 데도 사용됩니다. 테이블, 역할, 문화권 및 큐브 뷰와 같은 개별 파일로 직렬화되는 TMDL 개체에서 소스 제어 diff를 사용하지 않도록 하는 것이 특히 중요합니다. ref 키워드는 부모 개체 TMDL 파일에서 TOM에서 항목 순서를 선언하는 데 사용됩니다.
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 키워드를 사용하여 참조됩니다.
- 항목이 하나만 있는 컬렉션은 ref를 내보내지 않습니다.
- 동일한 개체 형식인 경우 ref 사이에 빈 줄이 내보내지지 않습니다.
속성 값 구분 기호
속성 값을 할당하는 데는 두 개의 구분 기호/기호만 있습니다.
Equals(=)
콜론 (:)
- 모든 비식 속성 값사용됩니다. 모델 참조를 포함하는 속성을 포함합니다.
들여쓰기
TMDL은 TOM 계층 구조체를 나타내는 엄격한 공백 들여쓰기 규칙을 사용합니다. TMDL 문서는 기본 단일 탭 들여쓰기 규칙을 사용합니다.
각 개체에는 세 가지 수준의 들여쓰기 수준이 있을 수 있습니다.
- 수준 1 - 개체 선언
- 수준 2 - 개체 속성
- 수준 3 - 개체 속성 다중 줄 식
- 수준 2 - 개체 속성
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의 데이터베이스 및 직접 자식 개체는 루트 모델 또는 데이터베이스 아래에 중첩된 것으로 암시적으로 가정되므로 들여쓰기할 필요가 없습니다.
- 모델
- 테이블
- 공유 식
- 역할
- 문화
- 관점
- 관계
- 데이터 원본
- 쿼리 그룹
- 모델 수준 주석
- 모델 수준 확장 속성
이러한 들여오기 규칙을 따르지 않으면 구문 분석 오류가 발생합니다.
공백
기본적으로 TMDL은 백틱(```) 또는 큰따옴표("내에 묶이지 않은 경우 속성 및 식 값 내의 공백에 다음 규칙을 적용합니다.
- 속성 값에서 선행 및 후행 공백은 잘립니다.
- 식의 경우 식 끝에 있는 공백 줄이 삭제됩니다.
- 공백 선은 빈 선(공백/탭 없음)으로 잘립니다.
케이싱
serialize/쓰기에 대한 기본 TMDL API는 다음과 같이 적용되는 camelCase
- 개체 형식
- 키워드
- 열거형 값
역직렬화/읽기에서 TMDL API는 대/소문자를 구분하지 않습니다.
관련 콘텐츠
이제 TMDL을 이해했으므로 TMDL 시작하기