JSON 로딩

JSON 로딩 (Loading JSON)

DuckDB의 JSON 리더는 JSON 파일을 분석해서 어떤 설정 플래그를 써야 할지 스스로 추론합니다. 대부분의 상황에서 이 방식이 잘 동작하므로, 가장 먼저 시도해보는 것이 좋습니다. 드물게 JSON 리더가 올바른 설정을 알아내지 못하는 상황에서는, 설정을 직접 지정해서 JSON 파일을 올바르게 파싱할 수 있습니다.

출처: 공식문서

read_json 함수

read_json은 JSON 파일을 로딩하는 가장 간단한 방법입니다. JSON 리더의 올바른 설정을 자동으로 알아내려고 시도하고, 컬럼의 타입도 자동으로 추론합니다. 아래 예제에서는 todos.json 파일을 사용합니다.

SELECT *
FROM read_json('todos.json')
LIMIT 5;
userId id title completed
1 1 delectus aut autem false
1 2 quis ut nam facilis et officia qui false
1 3 fugiat veniam minus false
1 4 et porro tempora true
1 5 laboriosam mollitia et enim quasi adipisci quia provident illum false

read_json을 사용해 영구 테이블을 만들 수도 있습니다.

CREATE TABLE todos AS
    SELECT *
    FROM read_json('todos.json');
DESCRIBE todos;
column_name column_type null key default extra
userId UBIGINT YES NULL NULL NULL
id UBIGINT YES NULL NULL NULL
title VARCHAR YES NULL NULL NULL
completed BOOLEAN YES NULL NULL NULL

일부 컬럼에 대해서만 타입을 지정하면, read_json은 지정하지 않은 컬럼을 제외합니다.

SELECT *
FROM read_json(
        'todos.json',
        columns = {userId: 'UBIGINT', completed: 'BOOLEAN'}
    )
LIMIT 5;

userIdcompleted 컬럼만 표시되는 점을 확인하세요.

userId completed
1 false
1 false
1 false
1 true
1 false

여러 파일을 한 번에 읽으려면 glob 패턴이나 파일 목록을 제공하면 됩니다. 자세한 내용은 multiple files 섹션을 참고하세요.

JSON 객체를 읽는 함수 (Functions for Reading JSON Objects)

JSON을 읽는 데 사용되는 테이블 함수는 다음과 같습니다.

Function Description
read_json_objects(filename) filename에서 JSON 객체 하나를 읽습니다. filename은 파일 목록이나 glob 패턴일 수도 있습니다.
read_ndjson_objects(filename) format 파라미터를 newline_delimited로 설정한 read_json_objects의 별칭.
read_json_objects_auto(filename) format 파라미터를 auto로 설정한 read_json_objects의 별칭.

파라미터 (Parameters)

이 함수들의 파라미터는 다음과 같습니다.

Name Description Type Default
compression 파일의 압축 타입. 기본적으로 파일 확장자에서 자동 감지됩니다(예: t.json.gz는 gzip, t.json은 none). 옵션은 none, gzip, zstd, auto_detect. VARCHAR auto_detect
filename 결과에 추가 filename 컬럼을 포함할지 여부. DuckDB v1.3.0부터 filename 컬럼은 가상 컬럼으로 자동 추가되어, 이 옵션은 호환성 목적으로만 유지됩니다. BOOL false
format auto, unstructured, newline_delimited, array 중 하나. VARCHAR array
hive_partitioning 경로를 Hive 파티셔닝으로 해석할지 여부. BOOL (auto-detected)
ignore_errors 파싱 오류를 무시할지 여부(format이 newline_delimited일 때만 가능). BOOL false
maximum_sample_files 자동 감지를 위해 샘플링할 최대 JSON 파일 수. BIGINT 32
maximum_object_size JSON 객체의 최대 크기(바이트). UINTEGER 16777216

format 파라미터는 파일에서 JSON을 어떻게 읽을지 지정합니다. unstructured로 설정하면 최상위 JSON을 읽습니다. 예를 들어 birds.json:

{
  "duck": 42
}
{
  "goose": [1, 2, 3]
}
FROM read_json_objects('birds.json', format = 'unstructured');

두 개의 객체를 읽는 결과가 됩니다.

┌──────────────────────────────┐
│             json             │
│             json             │
├──────────────────────────────┤
│ {\n    "duck": 42\n}         │
│ {\n    "goose": [1, 2, 3]\n} │
└──────────────────────────────┘

newline_delimited로 설정하면 NDJSON을 읽습니다. 여기서는 각 JSON이 개행(\n)으로 구분됩니다. 예를 들어 birds-nd.json:

{"duck": 42}
{"goose": [1, 2, 3]}
FROM read_json_objects('birds-nd.json', format = 'newline_delimited');

역시 두 개의 객체를 읽습니다.

┌──────────────────────┐
│         json         │
│         json         │
├──────────────────────┤
│ {"duck": 42}         │
│ {"goose": [1, 2, 3]} │
└──────────────────────┘

array로 설정하면 배열의 각 요소를 읽습니다. 예를 들어 birds-array.json:

[
    {
        "duck": 42
    },
    {
        "goose": [1, 2, 3]
    }
]
FROM read_json_objects('birds-array.json', format = 'array');

역시 두 개의 객체를 읽습니다.

┌──────────────────────────────────────┐
│                 json                 │
│                 json                 │
├──────────────────────────────────────┤
│ {\n        "duck": 42\n    }         │
│ {\n        "goose": [1, 2, 3]\n    } │
└──────────────────────────────────────┘

JSON을 테이블로 읽는 함수 (Functions for Reading JSON as a Table)

DuckDB는 다음 함수들을 사용해 JSON을 테이블로 읽는 것도 지원합니다.

Function Description
read_json(filename) filename에서 JSON을 읽습니다. filename은 파일 목록이나 glob 패턴일 수도 있습니다.
read_json_auto(filename) read_json의 별칭.
read_ndjson(filename) format 파라미터를 newline_delimited로 설정한 read_json의 별칭.
read_ndjson_auto(filename) format 파라미터를 newline_delimited로 설정한 read_json의 별칭.

파라미터 (Parameters)

위 함수들은 maximum_object_size, format, ignore_errors, compression 외에 다음 파라미터를 추가로 가집니다.

Name Description Type Default
auto_detect 키 이름과 값의 데이터 타입을 자동으로 감지할지 여부 BOOL true
columns JSON 파일 안에 포함된 키 이름과 값 타입을 지정하는 struct(예: {key1: 'INTEGER', key2: 'VARCHAR'}). auto_detect가 켜져 있으면 추론됨 STRUCT (empty)
dateformat 날짜 파싱에 사용할 날짜 형식 VARCHAR iso
maximum_depth 자동 스키마 감지가 타입을 감지하는 최대 중첩 깊이. -1로 설정하면 중첩 JSON 타입을 완전히 감지 BIGINT -1
records auto, true, false 중 하나 VARCHAR auto
sample_size 자동 JSON 타입 감지를 위한 샘플 객체 수. 전체 입력 파일을 스캔하려면 -1 UBIGINT 20480
timestampformat 타임스탬프 파싱에 사용할 날짜 형식. iso(기본값)로 설정하면 시간대 오프셋이 있는 ISO 8601 타임스탬프(예: 2024-01-01T12:00:00+05:00)와 분수 초(예: 2024-01-01T12:00:00.123Z)를 자동으로 TIMESTAMP로 추론 VARCHAR iso
union_by_name 여러 JSON 파일의 스키마를 통합할지 여부 BOOL false
map_inference_threshold 스키마를 자동 감지할 컬럼 수에 대한 임계값 제어. JSON 스키마 자동 감지가 이 임계값보다 많은 서브필드를 가진 필드에 대해 STRUCT 타입을 추론하면, 대신 MAP 타입을 추론. -1로 설정하면 MAP 추론 비활성화 BIGINT 200
field_appearance_threshold JSON 리더가 각 JSON 필드의 등장 횟수를 자동 감지 샘플 크기로 나눔. 객체의 필드 평균이 이 임계값보다 작으면, 병합된 필드 타입의 값 타입을 가진 MAP 타입을 기본으로 사용 DOUBLE 0.1

DuckDB는 JSON 배열을 내부 LIST 타입으로 직접 변환하고, 누락된 키는 NULL이 된다는 점을 참고하세요.

SELECT *
FROM read_json(
    ['birds1.json', 'birds2.json'],
    columns = {duck: 'INTEGER', goose: 'INTEGER[]', swan: 'DOUBLE'}
);
duck goose swan
42 [1, 2, 3] NULL
43 [4, 5, 6] 3.3

DuckDB는 다음과 같이 타입을 자동으로 감지할 수도 있습니다.

SELECT goose, duck FROM read_json('*.json.gz');
SELECT goose, duck FROM '*.json.gz'; -- 동일한 의미

DuckDB는 format 파라미터로 지정되는 다양한 형식을 읽고 자동 감지할 수 있습니다. 배열을 포함한 JSON 파일을 조회하면, 예를 들어:

[
  {
    "duck": 42,
    "goose": 4.2
  },
  {
    "duck": 43,
    "goose": 4.3
  }
]

unstructured JSON을 포함한 파일(예: 아래)과 정확히 같은 방식으로 조회할 수 있습니다.

{
    "duck": 42,
    "goose": 4.2
}
{
    "duck": 43,
    "goose": 4.3
}

둘 다 같은 테이블로 읽을 수 있습니다.

SELECT
FROM read_json('birds.json');
duck goose
42 4.2
43 4.3

JSON 파일에 "records"가 없는 경우, 즉 객체가 아닌 다른 타입의 JSON이라도 DuckDB는 읽을 수 있습니다. 이때 records 파라미터로 지정합니다. records 파라미터는 JSON 안에 개별 컬럼으로 풀어야 하는 레코드가 들어 있는지 여부를 지정하며, DuckDB는 이를 자동 감지하려고 시도하기도 합니다. 예를 들어 birds-records.json 파일을 보겠습니다.

{"duck": 42, "goose": [1, 2, 3]}
{"duck": 43, "goose": [4, 5, 6]}
SELECT *
FROM read_json('birds-records.json');

이 쿼리는 두 개의 컬럼을 결과로 냅니다.

duck goose
42 [1,2,3]
43 [4,5,6]

같은 파일을 records를 false로 설정해서 읽으면, 데이터를 담은 STRUCT 하나(단일 컬럼)로 읽을 수 있습니다.

json
{'duck': 42, 'goose': [1,2,3]}
{'duck': 43, 'goose': [4,5,6]}

더 복잡한 데이터를 읽는 추가 예제는 "Shredding Deeply Nested JSON, One Vector at a Time" 블로그 포스트를 참고하세요.

FORMAT json과 COPY 문 (Loading with the COPY Statement)

json 확장이 설치되어 있으면 FORMAT json을 COPY FROM, IMPORT DATABASE, COPY TO, EXPORT DATABASE에서 모두 지원합니다. 자세한 내용은 COPY 문과 IMPORT / EXPORT 절을 참고하세요.

기본적으로 COPY는 newline-delimited JSON을 기대합니다. JSON 배열로 데이터를 복사하고 싶다면 ARRAY true를 지정하면 됩니다.

COPY (SELECT * FROM range(5) r(i))
TO 'numbers.json' (ARRAY true);

다음 파일이 생성됩니다.

[
	{"i":0},
	{"i":1},
	{"i":2},
	{"i":3},
	{"i":4}
]

이것을 다시 DuckDB로 읽으려면 다음과 같이 합니다.

CREATE TABLE numbers (i BIGINT);
COPY numbers FROM 'numbers.json' (ARRAY true);

형식은 다음과 같이 자동 감지할 수도 있습니다.

CREATE TABLE numbers (i BIGINT);
COPY numbers FROM 'numbers.json' (AUTO_DETECT true);

자동 감지된 스키마로 테이블을 만들 수도 있습니다.

CREATE TABLE numbers AS
    FROM 'numbers.json';

파라미터 (Parameters)

Name Description Type Default
auto_detect 키 이름과 값의 데이터 타입을 자동으로 감지할지 여부 BOOL false
columns JSON 파일 안에 포함된 키 이름과 값 타입을 지정하는 struct(예: {key1: 'INTEGER', key2: 'VARCHAR'}). auto_detect가 켜져 있으면 추론됨 STRUCT (empty)
compression 파일의 압축 타입. 기본적으로 파일 확장자에서 자동 감지. 옵션은 uncompressed, gzip, zstd, auto_detect VARCHAR auto_detect
convert_strings_to_integers 정수값을 나타내는 문자열을 숫자 타입으로 변환할지 여부 BOOL false
dateformat 날짜 파싱에 사용할 날짜 형식 VARCHAR iso
filename 결과에 추가 filename 컬럼을 포함할지 여부 BOOL false
format auto, unstructured, newline_delimited, array 중 하나 VARCHAR array
hive_partitioning 경로를 Hive 파티셔닝으로 해석할지 여부 BOOL false
ignore_errors 파싱 오류를 무시할지 여부(format이 newline_delimited일 때만 가능) BOOL false
maximum_depth 자동 스키마 감지가 타입을 감지하는 최대 중첩 깊이. -1로 설정하면 중첩 JSON 타입을 완전히 감지 BIGINT -1
maximum_object_size JSON 객체의 최대 크기(바이트) UINTEGER 16777216
records auto, true, false 중 하나 VARCHAR records
sample_size 자동 JSON 타입 감지를 위한 샘플 객체 수. 전체 입력 파일을 스캔하려면 -1 UBIGINT 20480
timestampformat 타임스탬프 파싱에 사용할 날짜 형식 VARCHAR iso
union_by_name 여러 JSON 파일의 스키마를 통합할지 여부 BOOL false

더 알아보기 (Learn more)