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_resultsetformat_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`|

더 알아보기 (Learn more)