DuckDB JSON 阅读器可以通过分析 JSON 文件自动推断出要使用的配置标志。在大多数情况下,这将正常工作,应该是首先尝试的选项。在极少数情况下,如果 JSON 阅读器无法确定正确的配置,可以手动配置 JSON 阅读器以正确解析 JSON 文件。
The read_json
函数
read_json
是加载 JSON 文件的最简单方法:它会自动尝试找出 JSON 读取器的正确配置。它还会自动推断列的类型。
在以下示例中,我们使用了 todos.json
文件,
SELECT *
FROM read_json('todos.json')
LIMIT 5;
用户ID | ID | 标题 | 完成状态 |
---|---|---|---|
1 | 1 | 删除自动 | false |
1 | 2 | quis ut nam facilis et officia qui | false |
1 | 3 | 逃避的缺点 | false |
1 | 4 | 以及更多的时间 | true |
1 | 5 | 辛勤工作的软体动物和几乎像提供光明的购物 | 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 | 是 | NULL | NULL | NULL |
id | UBIGINT | 是 | 空 | 空 | 空 |
标题 | VARCHAR | 是 | 空 | 空 | 空 |
已完成 | 布尔值 | 是 | 空 | 空 | 空 |
如果我们指定列,我们可以绕过自动检测。请注意,并非所有列都需要指定:
SELECT *
FROM read_json(
'todos.json',
columns = {userId: 'UBIGINT', completed: 'BOOLEAN'}
);
可以通过提供通配符或文件列表一次性读取多个文件。更多信息请参考多文件部分。
读取JSON对象的函数
以下表格函数用于读取JSON:
Function | Description |
---|---|
read_json_objects(filename) |
从filename 读取一个JSON对象,其中filename 也可以是文件列表或通配符模式。 |
read_ndjson_objects(filename) |
是read_json_objects 的别名,参数format 设置为'newline_delimited' 。 |
read_json_objects_auto(filename) |
是 read_json_objects 的别名,参数 format 设置为 'auto' 。 |
Parameters
这些函数具有以下参数:
Name | Description | Type | Default |
---|---|---|---|
compression |
文件的压缩类型。默认情况下,这将根据文件扩展名自动检测(例如,t.json.gz 将使用 gzip,t.json 将不使用压缩)。选项包括 'none' 、'gzip' 、'zstd' 和 'auto' 。 |
VARCHAR |
'auto' |
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_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('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 读取为表格:
Function | Description |
---|---|
read_json(filename) |
从filename 读取JSON,其中filename 也可以是文件列表或通配符模式。 |
read_json_auto(filename) |
read_json 的别名。 |
read_ndjson(filename) |
是 read_json 的别名,参数 format 设置为 'newline_delimited' 。 |
read_ndjson_auto(filename) |
是 read_json 的别名,参数 format 设置为 'newline_delimited' 。 |
Parameters
除了maximum_object_size
、format
、ignore_errors
和compression
之外,这些函数还有额外的参数:
Name | Description | Type | Default |
---|---|---|---|
auto_detect |
是否自动检测键的名称和值的数据类型 | BOOL |
false |
columns |
一个结构体,指定JSON文件中包含的键名和值类型(例如,{key1: 'INTEGER', key2: 'VARCHAR'} )。如果启用了auto_detect ,这些将被推断出来 |
STRUCT |
(empty) |
dateformat |
指定解析日期时使用的日期格式。请参阅 日期格式 | VARCHAR |
'iso' |
maximum_depth |
自动模式检测检测类型的最大嵌套深度。设置为-1以完全检测嵌套的JSON类型 | BIGINT |
-1 |
records |
可以是 ['auto', 'true', 'false'] 中的一个 |
VARCHAR |
'records' |
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 类型,其值类型为合并的字段类型。 |
0.1 |
请注意,DuckDB 可以直接将 JSON 数组转换为其内部的 LIST
类型,缺失的键将变为 NULL
:
SELECT *
FROM read_json(
['birds1.json', 'birds2.json'],
columns = {duck: 'INTEGER', goose: 'INTEGER[]', swan: 'DOUBLE'}
);
鸭子 | 鹅 | 天鹅 |
---|---|---|
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的JSON文件一样进行查询,例如:
{
"duck": 42,
"goose": 4.2
}
{
"duck": 43,
"goose": 4.3
}
两者都可以读取为表格:
鸭子 | 鹅 |
---|---|
42 | 4.2 |
43 | 4.3 |
如果你的JSON文件不包含'records',即任何非对象类型的JSON,DuckDB仍然可以读取它。
这是通过records
参数指定的。
records
参数指定了JSON是否包含应解包到单独列中的记录,即使用records
读取以下文件:
{"duck": 42, "goose": [1, 2, 3]}
{"duck": 43, "goose": [4, 5, 6]}
结果显示为两列:
鸭子 | 鹅 |
---|---|
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
扩展时,FORMAT JSON
支持COPY FROM
、IMPORT DATABASE
,以及COPY TO
和EXPORT DATABASE
。请参阅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';
Parameters
Name | Description | Type | Default |
---|---|---|---|
auto_detect |
是否自动检测键的名称和值的数据类型 | BOOL |
false |
columns |
A struct that specifies the key names and value types contained within the JSON file (e.g., {key1: 'INTEGER', key2: 'VARCHAR'} ). If auto_detect is enabled these will be inferred |
STRUCT |
(empty) |
compression |
文件的压缩类型。默认情况下,这将根据文件扩展名自动检测(例如,t.json.gz 将使用 gzip,t.json 将不使用压缩)。选项包括 'uncompressed' 、'gzip' 、'zstd' 和 'auto_detect' 。 |
VARCHAR |
'auto_detect' |
convert_strings_to_integers |
表示整数值的字符串是否应转换为数值类型。 | BOOL |
false |
dateformat |
Specifies the date format to use when parsing dates. See Date Format | VARCHAR |
'iso' |
filename |
Whether or not an extra filename column should be included in the result. |
BOOL |
false |
format |
可以是以下之一 ['auto', 'unstructured', 'newline_delimited', 'array'] |
VARCHAR |
'array' |
hive_partitioning |
Whether or not to interpret the path as a Hive partitioned path. | BOOL |
false |
ignore_errors |
是否忽略解析错误(仅在format 为'newline_delimited' 时可能) |
BOOL |
false |
maximum_depth |
Maximum nesting depth to which the automatic schema detection detects types. Set to -1 to fully detect nested JSON types | BIGINT |
-1 |
maximum_object_size |
JSON对象的最大大小(以字节为单位) | UINTEGER |
16777216 |
records |
Can be one of ['auto', 'true', 'false'] |
VARCHAR |
'records' |
sample_size |
Option to define number of sample objects for automatic JSON type detection. Set to -1 to scan the entire input file | UBIGINT |
20480 |
timestampformat |
Specifies the date format to use when parsing timestamps. See Date Format | VARCHAR |
'iso' |
union_by_name |
是否应将多个JSON文件的模式统一。 | BOOL |
false |