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;
请注意,此处仅显示 userId
和 completed
列
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 将不使用压缩)。选项包括 none 、gzip 、zstd 和 auto_detect 。 |
VARCHAR |
auto_detect |
文件名 |
结果中是否应包含一个额外的 filename 列。自 DuckDB v1.3.0 起,filename 列已自动作为虚拟列添加,此选项仅为兼容性原因而保留。 |
BOOL |
false |
format |
可以是 auto 、unstructured 、newline_delimited 和 array 之一。 |
VARCHAR |
array |
hive_partitioning |
是否将路径解释为 Hive 分区路径。 | BOOL |
(自动检测) |
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 作为表读取的函数
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_size
、format
、ignore_errors
和 compression
之外,这些函数还有其他参数
名称 | 描述 | 类型 | 默认值 |
---|---|---|---|
auto_detect |
是否自动检测键的名称和值的数据类型 | BOOL |
true |
columns |
一个结构体,用于指定 JSON 文件中包含的键名和值类型(例如,{key1: 'INTEGER', key2: 'VARCHAR'} )。如果启用了 auto_detect ,则会推断这些信息。 |
STRUCT |
(空) |
dateformat |
指定解析日期时要使用的日期格式。请参阅 日期格式 | VARCHAR |
iso |
maximum_depth |
自动模式检测检测类型的最大嵌套深度。设置为 -1 可完全检测嵌套 JSON 类型 | BIGINT |
-1 |
records |
可以是 auto 、true 、false 之一 |
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 FROM
、IMPORT DATABASE
以及 COPY TO
和 EXPORT 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 将不使用压缩)。选项包括 uncompressed 、gzip 、zstd 和 auto_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 |
是否忽略解析错误(仅当 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 |