You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DuckDB 0.7.1加载嵌套JSON时Struct数组类型报错求助

解决DuckDB导入嵌套JSON时Struct数组报错及分表方案

核心问题排查

你遇到的Unsupported result column Struct()[]错误,大概率是手动声明Schema时Struct数组的语法格式错误,或者JSON结构与Schema定义不匹配导致的。DuckDB对Struct数组的正确格式要求是ARRAY<STRUCT<字段名: 数据类型, ...>>,而非其他写法。

分步解决方案

1. 先确认JSON统一结构

先通过json_structure确认所有25000个文件的JSON结构是否一致,避免因个别文件结构差异导致导入失败:

SELECT json_structure(read_json('你的JSON文件路径/*.json'));

根据返回的结构结果,精准定义后续的Schema。

2. 正确导入嵌套JSON(两种方式)

方式一:自动推断Schema(推荐)

让DuckDB自动识别JSON结构,避免手动写Schema出错:

-- 创建临时表存储原始JSON数据
CREATE TABLE raw_replays AS
SELECT * FROM read_json(
    '你的JSON文件路径/*.json',
    auto_detect=true,
    ignore_errors=true -- 可选:跳过结构异常的文件
);

导入后可以用DESCRIBE raw_replays;查看自动推断的Schema,确认Struct数组类型是否正确识别。

方式二:手动指定正确的Schema

如果自动推断不符合预期,按照ARRAY<STRUCT<...>>的格式手动编写Schema:

CREATE TABLE raw_replays AS
SELECT * FROM read_json(
    '你的JSON文件路径/*.json',
    schema='''{
        "ReplayID": VARCHAR,
        "GameMode": VARCHAR,
        "MapID": INTEGER,
        "Players": ARRAY<STRUCT<
            "PlayerID": VARCHAR,
            "TeamID": INTEGER,
            "HeroID": VARCHAR,
            "Talents": ARRAY<STRUCT<
                "TalentID": VARCHAR,
                "Level": INTEGER
            >>
        >>,
        "Draft": ARRAY<STRUCT<
            "PickOrder": INTEGER,
            "HeroID": VARCHAR,
            "Team": VARCHAR
        >>
        -- 其他字段按json_structure结果补充
    }'''
);

注意:Schema字符串要用三重引号包裹,避免内部引号冲突;字段名和类型要与JSON结构完全匹配(包括大小写)。

3. 拆分出目标表

导入完成后,通过UNNEST操作拆分嵌套数组,生成Replay、ReplayPlayers、PlayerTalents等表:

① 生成Replay主表(非嵌套字段)
CREATE TABLE Replay AS
SELECT
    ReplayID,
    GameMode,
    MapID,
    GameDuration,
    -- 所有顶层非数组、非嵌套字段
FROM raw_replays;
② 生成ReplayPlayers表(展开Players数组)
CREATE TABLE ReplayPlayers AS
SELECT
    r.ReplayID,
    p.PlayerID,
    p.TeamID,
    p.HeroID,
    p.IsWinner,
    -- Players结构体中的其他字段
FROM raw_replays r, UNNEST(r.Players) p;
③ 生成PlayerTalents表(展开Players里的Talents数组)
CREATE TABLE PlayerTalents AS
SELECT
    r.ReplayID,
    p.PlayerID,
    t.TalentID,
    t.Level,
    t.SelectedTime,
    -- Talents结构体中的其他字段
FROM raw_replays r, UNNEST(r.Players) p, UNNEST(p.Talents) t;

4. 解决from_json测试失败问题

如果单独用from_json解析Struct数组失败,检查以下两点:

  • 确保Schema字符串格式正确:比如'ARRAY<STRUCT<PickOrder: INTEGER, HeroID: VARCHAR>>'
  • 确保待解析的JSON字符串没有格式错误(比如缺失字段、类型不匹配)

测试示例:

-- 取一条数据测试from_json
SELECT from_json(
    Draft,
    'ARRAY<STRUCT<PickOrder: INTEGER, HeroID: VARCHAR, Team: VARCHAR>>'
) FROM raw_replays LIMIT 1;

内容的提问来源于stack exchange,提问作者Mitchell Hamann

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 20:03:08