Template
Template
Template 포맷은 다른 표준 포맷보다 더 많은 커스터마이즈가 필요할 때, 값의 자리 표시자(placeholder)가 있는 사용자 정의 포맷 문자열을 직접 지정할 수 있게 해주는 포맷이에요. 값의 이스케이프 규칙도 함께 지정할 수 있습니다.
출처: 문서
본문
| Input | Output | Alias |
|---|---|---|
| ✔ | ✔ |
Description
다른 표준 포맷이 제공하는 것보다 더 많은 커스터마이즈가 필요한 경우, Template 포맷을 사용하면 값의 자리 표시자와 데이터의 이스케이프 규칙을 지정해 나만의 커스텀 포맷 문자열을 정의할 수 있어요. 다음 설정들을 사용합니다:
| Setting | Description |
|---|---|
| format_template_row | 행의 포맷 문자열을 담은 파일의 경로를 지정해요. |
| format_template_resultset | 결과 집합의 포맷 문자열을 담은 파일의 경로를 지정해요. |
| format_template_rows_between_delimiter | 행 사이의 구분자를 지정해요. 마지막 행을 제외한 모든 행 뒤에 출력(또는 기대)됩니다(기본값 \n). |
| format_template_row_format | 행의 포맷 문자열을 인라인으로 지정해요. |
| format_template_resultset_format | 결과 집합 포맷 문자열을 인라인으로 지정해요. |
| 다른 포맷의 일부 설정(예: JSON 이스케이프를 쓸 때의 output_format_json_quote_64bit_integers) |
Settings and escaping rules
format_template_row
format_template_row 설정은 다음과 같은 문법의 행 포맷 문자열을 담은 파일 경로를 지정해요:
delimiter_1${column_1:serializeAs_1}delimiter_2${column_2:serializeAs_2} ... delimiter_N
여기서:
| Part of syntax | Description |
|---|---|
| delimiter_i | 값 사이의 구분자예요( $ 기호는 $$ 로 이스케이프할 수 있어요). |
| column_i | 선택하거나 삽입할 값이 있는 열의 이름 또는 인덱스예요(비어 있으면 그 열은 건너뜁니다). |
| serializeAs_i | 열 값에 대한 이스케이프 규칙이에요. |
다음 이스케이프 규칙이 지원됩니다:
| Escaping Rule | Description |
|---|---|
| CSV , JSON , XML | 같은 이름의 포맷과 유사해요. |
| Escaped | TSV와 유사해요. |
| Quoted | Values와 유사해요. |
| Raw | 이스케이프 없이, TSVRaw와 유사해요. |
| None | 이스케이프 규칙 없음 — 아래 참고를 확인하세요. |
이스케이프 규칙이 생략되면 None이 사용됩니다. XML은 출력 전용으로만 적합해요.
예시를 살펴볼게요. 다음과 같은 포맷 문자열이 주어졌을 때:
Search phrase: ${s:Quoted}, count: ${c:Escaped}, ad price: $$${p:JSON};
다음 값들이 각각 Search phrase:, , count:, , ad price: $와 ; 구분자 사이에 출력되거나(SELECT 사용 시) 기대됩니다(INPUT 사용 시):
- s (이스케이프 규칙 Quoted)
- c (이스케이프 규칙 Escaped)
- p (이스케이프 규칙 JSON)
예를 들어:
- INSERT 하는 경우 아래 줄은 기대 템플릿과 일치하며, 값 bathroom interior design , 2166 , $3 을 열 Search phrase , count , ad price 로 읽을 거예요.
- SELECT 하는 경우 아래 줄은 출력이고, 값 bathroom interior design , 2166 , $3 가 이미 열 Search phrase , count , ad price 아래 테이블에 저장되어 있다고 가정해요.
Search phrase: 'bathroom interior design', count: 2166, ad price: $3;
format_template_rows_between_delimiter
format_template_rows_between_delimiter 설정은 행 사이의 구분자를 지정해요. 마지막 행을 제외한 모든 행 뒤에 출력(또는 기대)됩니다(기본값 \n).
format_template_resultset
format_template_resultset 설정은 결과 집합의 포맷 문자열을 담은 파일의 경로를 지정해요. 결과 집합의 포맷 문자열은 행의 포맷 문자열과 같은 문법을 가집니다.
접두사, 접미사, 그리고 추가 정보를 출력하는 방법을 지정할 수 있으며, 열 이름 대신 다음 자리 표시자를 포함해요:
- data는 format_template_row 포맷의 데이터 행들로, format_template_rows_between_delimiter로 구분된 값이에요. 이 자리 표시자는 포맷 문자열의 첫 번째 자리 표시자여야 해요.
- totals는 format_template_row 포맷의 합계 값이 있는 행이에요(WITH TOTALS를 쓸 때).
- min은 format_template_row 포맷의 최솟값이 있는 행이에요(extremes가 1로 설정될 때).
- max는 format_template_row 포맷의 최댓값이 있는 행이에요(extremes가 1로 설정될 때).
- rows는 출력 전체 행 수예요.
- rows_before_limit는 LIMIT이 없었다면 존재했을 최소 행 수예요. 쿼리에 LIMIT이 포함된 경우에만 출력돼요. 쿼리에 GROUP BY가 포함되면 rows_before_limit_at_least는 LIMIT이 없었다면 존재했을 정확한 행 수예요.
- time은 요청 실행 시간(초)이에요.
- rows_read는 읽은 행 수예요.
- bytes_read는 읽은 바이트 수(압축되지 않은)예요.
자리 표시자 data, totals, min, max는 이스케이프 규칙을 지정하면 안 되며(또는 None을 명시적으로 지정해야 해요), 나머지 자리 표시자는 어떤 이스케이프 규칙도 지정할 수 있어요. format_template_resultset 설정이 빈 문자열이면 ${data}가 기본값으로 사용됩니다. INSERT 쿼리의 경우 접두사나 접미사(아래 예시 참고)에 따라 일부 열이나 필드를 건너뛸 수 있어요.
In-line specification
템플릿 포맷의 포맷 설정(format_template_row, format_template_resultset)을 클러스터의 모든 노드에 있는 디렉터리에 배포하는 것이 어렵거나 불가능한 경우가 많아요. 게다가 포맷이 너무 단순해서 파일로 만들 필요가 없을 수도 있어요. 이런 경우 format_template_row_format(format_template_row용)과 format_template_resultset_format(format_template_resultset용)을 사용해 템플릿 문자열을 파일 경로 대신 쿼리에 직접 지정할 수 있어요. 포맷 문자열과 이스케이프 시퀀스의 규칙은 다음과 동일해요:
- format_template_row_format을 쓸 때의 format_template_row.
- format_template_resultset_format을 쓸 때의 format_template_resultset.
Example usage
Template 포맷을 사용하는 예시를 두 가지 살펴볼게요. 먼저 데이터를 선택하고, 그다음 데이터를 삽입해요.
Selecting data
Query
SELECT SearchPhrase, count() AS c FROM test.hits GROUP BY SearchPhrase ORDER BY c DESC LIMIT 5 FORMAT Template SETTINGS
format_template_resultset = '/some/path/resultset.format', format_template_row = '/some/path/row.format', format_template_rows_between_delimiter = '\n '
/some/path/resultset.format
<!DOCTYPE HTML>
<html> <head> <title>Search phrases</title> </head>
<body>
<table border="1"> <caption>Search phrases</caption>
<tr> <th>Search phrase</th> <th>Count</th> </tr>
${data}
</table>
<table border="1"> <caption>Max</caption>
${max}
</table>
<b>Processed ${rows_read:XML} rows in ${time:XML} sec</b>
</body>
</html>
/some/path/row.format
<tr> <td>${0:XML}</td> <td>${1:XML}</td> </tr>
Response
<!DOCTYPE HTML>
<html> <head> <title>Search phrases</title> </head>
<body>
<table border="1"> <caption>Search phrases</caption>
<tr> <th>Search phrase</th> <th>Count</th> </tr>
<tr> <td></td> <td>8267016</td> </tr>
<tr> <td>bathroom interior design</td> <td>2166</td> </tr>
<tr> <td>clickhouse</td> <td>1655</td> </tr>
<tr> <td>spring 2014 fashion</td> <td>1549</td> </tr>
<tr> <td>freeform photos</td> <td>1480</td> </tr>
</table>
<table border="1"> <caption>Max</caption>
<tr> <td></td> <td>8873898</td> </tr>
</table>
<b>Processed 3095973 rows in 0.1569913 sec</b>
</body>
</html>
Inserting data
Some header
Page views: 5, User id: 4324182021466249494, Useless field: hello, Duration: 146, Sign: -1
Page views: 6, User id: 4324182021466249494, Useless field: world, Duration: 185, Sign: 1
Total rows: 2
INSERT INTO UserActivity SETTINGS
format_template_resultset = '/some/path/resultset.format', format_template_row = '/some/path/row.format'
FORMAT Template
/some/path/resultset.format
Some header\n${data}\nTotal rows: ${:CSV}\n
/some/path/row.format
Page views: ${PageViews:CSV}, User id: ${UserID:CSV}, Useless field: ${:CSV}, Duration: ${Duration:CSV}, Sign: ${Sign:CSV}
자리 표시자 안의 PageViews, UserID, Duration, Sign은 테이블의 열 이름이에요. 행에서 Useless field 뒤의 값과 접미사의 \nTotal rows: 뒤 값은 무시됩니다. 입력 데이터의 모든 구분자는 지정된 포맷 문자열의 구분자와 엄격히 같아야 해요.
In-line specification
마크다운 테이블을 손으로 만드는 게 지겹나요? 이 예시에서는 Template 포맷과 인라인 지정 설정을 사용해 system.formats 테이블에서 몇몇 ClickHouse 포맷 이름을 SELECT해서 마크다운 테이블로 만드는 간단한 작업을 해볼게요. Template 포맷과 format_template_row_format, format_template_resultset_format 설정을 사용하면 쉽게 할 수 있어요.
이전 예시에서는 결과 집합과 행 포맷 문자열을 별도 파일로 지정하고, 각각의 경로를 format_template_resultset과 format_template_row 설정으로 지정했어요. 이번에는 템플릿이 마크다운 테이블을 만들기 위한 몇 개의 |와 -만으로 이루어진 단순한 것이라 인라인으로 처리할게요. 결과 집합 템플릿 문자열은 format_template_resultset_format 설정으로 지정해요. 테이블 헤더를 만들기 위해 ${data} 앞에 |ClickHouse Formats|\n|---|\n을 추가했어요. 행은 format_template_row_format 설정으로 |{0:XML}| 템플릿 문자열을 지정해요. Template 포맷은 주어진 포맷의 행들을 ${data} 자리 표시자에 삽입해 줍니다. 이 예시에서는 열이 하나뿐이지만, 더 추가하려면 행 템플릿 문자열에 {1:XML}, {2:XML}… 등을 추가하고 적절한 이스케이프 규칙을 선택하면 돼요. 이 예시에서는 이스케이프 규칙 XML을 사용했어요.
Query
WITH formats AS
(
SELECT * FROM system.formats
ORDER BY rand()
LIMIT 5
)
SELECT * FROM formats
FORMAT Template
SETTINGS
format_template_row_format='|`${0:XML}`|',
format_template_resultset_format='|ClickHouse Formats|\n|---|\n${data}\n'
보세요! 마크다운 테이블을 만들기 위해 그 많은 |와 -를 손으로 추가해야 하는 수고를 덜었어요.
Response
|ClickHouse Formats|
|---|
|`BSONEachRow`|
|`CustomSeparatedWithNames`|
|`Prometheus`|
|`DWARF`|
|`Avro`|