⌘+k ctrl+k
1.3 (稳定版)
搜索快捷键 cmd + k | ctrl + k
加载 JSON

DuckDB 的 JSON 读取器可以通过分析 JSON 文件自动推断要使用的配置标志。这在大多数情况下都能正常工作,并且应该是首先尝试的选项。在极少数情况下,如果 JSON 读取器无法确定正确的配置,则可以手动配置 JSON 读取器以正确解析 JSON 文件。

The read_json 函数

The 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 或文件列表一次读取多个文件。有关更多信息,请参阅多文件部分

用于读取 JSON 对象的函数

以下表函数用于读取 JSON

函数 描述
read_json_objects(filename) filename 读取 JSON 对象,其中 filename 也可以是文件列表或 glob 模式。
read_ndjson_objects(filename) read_json_objects 的别名,其参数 format 设置为 newline_delimited
read_json_objects_auto(filename) read_json_objects 的别名,其参数 format 设置为 auto

参数

这些函数具有以下参数

名称 描述 类型 默认值
compression 文件的压缩类型。默认情况下,将从文件扩展名自动检测(例如,t.json.gz 将使用 gzip,t.json 将不使用压缩)。选项包括 nonegzipzstdauto_detect VARCHAR auto_detect
文件名 结果中是否应包含一个额外的 filename 列。自 DuckDB v1.3.0 起,filename 列已自动作为虚拟列添加,此选项仅为兼容性原因而保留。 BOOL false
format 可以是 autounstructurednewline_delimitedarray 之一。 VARCHAR array
hive_partitioning 是否将路径解释为 Hive 分区路径 BOOL (自动检测)
ignore_errors 是否忽略解析错误(仅当 formatnewline_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 作为表读取的函数

DuckDB 还支持使用以下函数将 JSON 作为表读取

函数 描述
read_json(filename) filename 读取 JSON,其中 filename 也可以是文件列表或 glob 模式。
read_json_auto(filename) read_json 的别名。
read_ndjson(filename) read_json 的别名,其参数 format 设置为 newline_delimited
read_ndjson_auto(filename) read_json 的别名,其参数 format 设置为 newline_delimited

参数

除了 maximum_object_sizeformatignore_errorscompression 之外,这些函数还有其他参数

名称 描述 类型 默认值
auto_detect 是否自动检测键的名称和值的数据类型 BOOL true
columns 一个结构体,用于指定 JSON 文件中包含的键名和值类型(例如,{key1: 'INTEGER', key2: 'VARCHAR'})。如果启用了 auto_detect,则会推断这些信息。 STRUCT (空)
dateformat 指定解析日期时要使用的日期格式。请参阅 日期格式 VARCHAR iso
maximum_depth 自动模式检测检测类型的最大嵌套深度。设置为 -1 可完全检测嵌套 JSON 类型 BIGINT -1
records 可以是 autotruefalse 之一 VARCHAR auto
sample_size 用于定义自动 JSON 类型检测的样本对象数量的选项。设置为 -1 可扫描整个输入文件 UBIGINT 20480
timestampformat 指定解析时间戳时要使用的日期格式。请参阅 日期格式 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'; -- equivalent

DuckDB 可以读取(并自动检测)各种格式,这些格式由 format 参数指定。查询包含 array 的 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 文件不包含“记录”(即除了对象之外的任何其他类型的 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]}

有关读取更复杂数据的其他示例,请参阅“逐向量粉碎深度嵌套 JSON”博客文章

使用 COPY 语句和 FORMAT json 加载

当安装了 json 扩展时,COPY FROMIMPORT DATABASE 以及 COPY TOEXPORT DATABASE 都支持 FORMAT json。请参阅 COPY 语句IMPORT / EXPORT 子句

默认情况下,COPY 期望使用换行符分隔的 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';

参数

名称 描述 类型 默认值
auto_detect 是否自动检测键的名称和值的数据类型 BOOL false
columns 一个结构体,用于指定 JSON 文件中包含的键名和值类型(例如,{key1: 'INTEGER', key2: 'VARCHAR'})。如果启用了 auto_detect,则会推断这些信息。 STRUCT (空)
compression 文件的压缩类型。默认情况下,将从文件扩展名自动检测(例如,t.json.gz 将使用 gzip,t.json 将不使用压缩)。选项包括 uncompressedgzipzstdauto_detect VARCHAR auto_detect
convert_strings_to_integers 表示整数值的字符串是否应转换为数值类型。 BOOL false
dateformat 指定解析日期时要使用的日期格式。请参阅 日期格式 VARCHAR iso
文件名 结果中是否应包含一个额外的 filename 列。 BOOL false
format 可以是 auto, unstructured, newline_delimited, array 之一 VARCHAR array
hive_partitioning 是否将路径解释为 Hive 分区路径 BOOL false
ignore_errors 是否忽略解析错误(仅当 formatnewline_delimited 时可能) BOOL false
maximum_depth 自动模式检测检测类型的最大嵌套深度。设置为 -1 可完全检测嵌套 JSON 类型 BIGINT -1
maximum_object_size JSON 对象的最大大小(以字节为单位) UINTEGER 16777216
records 可以是 autotruefalse 之一 VARCHAR records
sample_size 用于定义自动 JSON 类型检测的样本对象数量的选项。设置为 -1 可扫描整个输入文件 UBIGINT 20480
timestampformat 指定解析时间戳时要使用的日期格式。请参阅 日期格式 VARCHAR iso
union_by_name 是否应 统一 多个 JSON 文件的模式。 BOOL false