Excel 익스텐션

Excel 익스텐션 (Excel Extension)

excel 익스텐션은 i18npool 라이브러리를 감싸서 Excel의 서식 규칙에 따라 숫자를 포맷하는 함수와 Excel(.xlsx) 파일을 읽고 쓰는 기능을 제공해요. 다만 .xls 파일은 지원하지 않는다는 점을 유의하세요.

출처: 문서

본문

excel 익스텐션은 i18npool 라이브러리를 감싸서 Excel의 서식 규칙에 따라 숫자를 포맷하는 함수와 Excel(.xlsx) 파일을 읽고 쓰는 기능을 제공해요. 다만 .xls 파일은 지원되지 않아요.

설치와 로드 (Installing and Loading)

excel 익스텐션은 공식 익스텐션 저장소에서 처음 사용할 때 투명하게 자동 로드돼요. 수동으로 설치하고 로드하려면:

INSTALL excel;
LOAD excel;

Excel 스칼라 함수 (Excel Scalar Functions)

함수 설명
excel_text(number, format_string) 주어진 numberformat_string의 규칙에 따라 포맷해요
text(number, format_string) excel_text의 별칭

예시 (Examples)

SELECT excel_text(1_234_567.897, 'h:mm AM/PM') AS timestamp;
timestamp
9:31 PM
SELECT excel_text(1_234_567.897, 'h AM/PM') AS timestamp;
timestamp
9 PM

XLSX 파일 읽기 (Reading XLSX Files)

.xlsx 파일을 읽는 것은 그저 즉시 SELECT하는 것만큼 간단해요:

SELECT *
FROM 'test.xlsx';
a b
1.0 2.0
3.0 4.0

하지만 가져오기 과정을 제어할 추가 옵션을 설정하고 싶다면 read_xlsx 함수를 대신 사용할 수 있어요. 다음 명명된 파라미터가 지원돼요.

옵션 타입 기본값 설명
header BOOLEAN 자동 추론 첫 행을 결과 컬럼의 이름을 담는 것으로 취급할지 여부.
sheet VARCHAR 자동 추론 읽을 xlsx 파일의 시트 이름. 기본은 첫 번째 시트.
all_varchar BOOLEAN false 모든 셀을 VARCHAR를 담는 것으로 읽을지 여부.
ignore_errors BOOLEAN false 에러를 무시하고 해당 추론 타입으로 캐스트할 수 없는 셀을 조용히 NULL로 대체할지 여부.
range VARCHAR 자동 추론 읽을 셀 범위(스프레드시트 표기). 예를 들어 A1:B2는 A1부터 B2까지의 셀을 읽어요. 지정하지 않으면 결과 범위는 연속된 비어 있지 않은 첫 행과 같은 컬럼들을 가로지르는 첫 빈 행 사이의 셀 직사각형 영역으로 추론돼요.
stop_at_empty BOOLEAN 자동 추론 빈 행을 만나면 파일 읽기를 중단할지 여부. 명시적 range 옵션이 제공되면 기본 false, 그렇지 않으면 true.
empty_as_varchar BOOLEAN false 컬럼 타입을 자동 추론할 때 빈 셀을 DOUBLE 대신 VARCHAR로 취급할지 여부.
SELECT *
FROM read_xlsx('test.xlsx', header = true);
a b
1.0 2.0
3.0 4.0

또는 XLSX 형식 옵션과 함께 COPY 문을 사용해 Excel 파일을 기존 테이블로 가져올 수 있어요. 이 경우 대상 테이블의 컬럼 타입이 Excel 파일 셀 타입을 강제(coerce)하는 데 사용돼요.

CREATE TABLE test (a DOUBLE, b DOUBLE);
COPY test FROM 'test.xlsx' WITH (FORMAT xlsx, HEADER);
SELECT * FROM test;

타입과 범위 추론 (Type and Range Inference)

Excel 자체는 셀에 숫자나 문자열만 실제로 저장하고 컬럼의 모든 셀이 같은 타입이어야 한다고 강제하지 않기 때문에, excel 익스텐션은 Excel 시트를 가져올 때 컬럼 타입을 "추론"하고 결정하기 위해 어느 정도 추측을 해야 해요. 거의 모든 컬럼이 DOUBLE 또는 VARCHAR로 추론되지만 몇 가지 주의할 점이 있어요:

  • TIMESTAMP, TIME, DATE, BOOLEAN 타입은 셀에 적용된 _형식(format)_에 따라 가능할 때 추론돼요.
  • TRUEFALSE를 담은 텍스트 셀은 BOOLEAN으로 추론돼요.
  • 빈 셀은 기본적으로 DOUBLE로 간주돼요. 단, empty_as_varchar 옵션을 true로 설정하면 VARCHAR로 타입이 정해져요.

all_varchar 옵션이 true로 설정되면 위 사항은 적용되지 않고 모든 셀이 VARCHAR로 읽혀요.

타입이 명시적으로 지정되지 않으면(예: COPY TO ... FROM '⟨file⟩.xlsx'{:.language-sql .highlight} 대신 read_xlsx 함수를 사용할 때), 결과 컬럼의 타입은 시트의 첫 "데이터" 행을 기준으로 추론돼요. 즉:

  • 명시적 범위가 주어지지 않으면
    • 헤더가 발견되거나 header 옵션으로 강제되면 헤더 다음 첫 행
    • 헤더가 발견되거나 강제되지 않으면 시트의 첫 번째 비어 있지 않은 행
  • 명시적 범위가 주어지면
    • 첫 행에서 헤더가 발견되거나 header 옵션으로 강제되면 범위의 두 번째 행
    • 헤더가 발견되거나 강제되지 않으면 범위의 첫 행

첫 "데이터 행"이 시트의 나머지를 대표하지 않으면(예: 빈 셀을 포함) 문제가 생길 수 있는데, 이 경우 ignore_errorsempty_as_varchar 옵션으로 해결할 수 있어요.

하지만 COPY TO ... FROM '⟨file⟩.xlsx'{:.language-sql .highlight} 문법을 사용하면 타입 추론이 수행되지 않고, 결과 컬럼의 타입은 가져오고 있는 테이블의 컬럼 타입으로 결정돼요. 모든 셀은 단순히 DOUBLE 또는 VARCHAR에서 대상 컬럼 타입으로 캐스트해서 변환돼요.

XLSX 파일 쓰기 (Writing XLSX Files)

.xlsx 파일 쓰기는 형식으로 XLSX를 지정한 COPY 문으로 지원돼요. 다음 추가 파라미터가 지원돼요.

옵션 타입 기본값 설명
header BOOLEAN false 컬럼 이름을 시트의 첫 행으로 쓸지 여부
sheet VARCHAR Sheet1 쓸 xlsx 파일의 시트 이름.
sheet_row_limit INTEGER 1048576 시트의 최대 행 수. 이 제한을 초과하면 에러가 발생해요.

경고 (Warning) 많은 도구가 시트에서 최대 1,048,576행만 지원하므로, sheet_row_limit을 늘리면 결과 파일이 다른 소프트웨어에서 읽을 수 없게 될 수 있어요.

이들은 FORMAT 뒤에 COPY 문의 옵션으로 전달돼요:

CREATE TABLE test AS
    SELECT *
    FROM (VALUES (1, 2), (3, 4)) AS t(a, b);
COPY test TO 'test.xlsx' WITH (FORMAT xlsx, HEADER true);

타입 변환 (Type Conversions)

XLSX 파일은 숫자나 문자열 — 즉 VARCHARDOUBLE에 해당하는 것만 실제로 저장할 수 있기 때문에, XLSX 파일을 쓸 때 다음 타입 변환이 적용돼요.

  • 숫자 타입은 XLSX 파일에 쓸 때 DOUBLE로 캐스팅돼요.
  • 시간(temporal) 타입(TIMESTAMP, DATE, TIME 등)은 Excel "시리얼" 숫자로 변환돼요 — 즉 날짜는 1900-01-01 이후 일 수, 시간은 하루의 분수. 그런 다음 "숫자 형식"으로 스타일링되어 Excel에서 열면 날짜나 시간으로 보여요.
  • TIMESTAMP_TZTIME_TZ는 각각 UTC TIMESTAMPTIME으로 캐스팅되는데, 시간대 정보는 유실돼요.
  • BOOLEAN10으로 변환되고, Excel에서 TRUEFALSE로 보이게 하는 "숫자 형식"이 적용돼요.
  • 그 외의 모든 타입은 VARCHAR로 캐스팅된 뒤 텍스트 셀로 작성돼요.

더 알아보기 (Learn more)