PAYATHON 2026

如何将 JSON 字典向量转换为 DolphinDB 内存表?

数据小许

可以先创建一个列类型明确的内存表,再逐个读取 respData 中的字典,按列顺序转换字段,并通过 tableInsert 写入。这样既能展开字典,也能将 r_z_top50cap 中的 null 保存为 DOUBLE 类型空值。

为什么原来的方法失败?

fromStdJson 会将 JSON 数组转换为向量,将对象转换为字典。JSON number 转换为 DOUBLE,null 转换为 NULL。字符串会先尝试转换为时序类型,转换失败则保留为字符串,因此 da 的实际类型要以解析结果为准。fromStdJson 文档

几种尝试遇到的问题各不相同:

  • table(respData) 将字典向量作为一列,没有按键展开。
  • each(transpose, respData) 逐个转换字典时遇到了未指定目标类型的空值。报错中的 [VOID] 表明该值无法直接作为表列的类型。
  • respData.values() 的调用对象是外层向量,不能直接收集内部各字典的字段。可以先取出字典,再通过 row["字段名"] 读取值。

transpose 支持将字典转换为表,但不会为这个报错中的 VOID 值确定 DOUBLE 列类型。transpose 文档

按固定列结构转换并写入

以下代码接在获取 resp 之后执行,前提是题目中的七个字段都存在、日期有效,且数值字段为数字或 null:

respData = fromStdJson(resp["text"])

colNames = `code`da`r_z_s`r_z_all`r_z_gics`r_z_sub_gics`r_z_top50cap
colTypes = [STRING, DATE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE]

t = table(100:0, colNames, colTypes)

for (row in respData) {
    daValue = row["da"]
    if (typestr(daValue) == "STRING") {
        daValue = temporalParse(daValue, "yyyy-MM-dd")
    }

    tableInsert(t, (
        string(row["code"]),
        date(daValue),
        double(row["r_z_s"]),
        double(row["r_z_all"]),
        double(row["r_z_gics"]),
        double(row["r_z_sub_gics"]),
        double(row["r_z_top50cap"])
    ))
}

select * from t

table(100:0, ...) 创建一个初始容量为 100、当前行数为 0 的内存表。每次 tableInsert 传入一个包含七个字段的 tuple,元素的位置和类型与目标表的七列对应。tableInsert 支持这种写法,并返回本次插入的行数。tableInsert 文档

代码中的类型处理包括:

  • 数值字段统一调用 double(...)。NULL 转换后会得到 DOUBLE 类型空值,保留缺失值的含义。官方示例中也有 double(NULL) 的用法。eqPercent 文档
  • 如果 da 仍为 STRING,就按 yyyy-MM-dd 解析;如果已经是时序类型,则通过 date(...) 转为 DATE。temporalParse 的格式分隔符需要与输入一致。temporalParse 文档

如何检查转换结果?

可以查看表结构和关键字段:

schema(t).colDefs
select code, da, r_z_top50cap from t

题目提供的 JSON 预期转换为 3 行、7 列:code 为 STRING,da 为 DATE,其余五列为 DOUBLE。r_z_top50cap 的第一行和第三行为 DOUBLE 空值,第二行为 2.1884785540779355。

使用时要注意什么?

列顺序由 colNames 和写入的 tuple 共同确定。读取字段时按键名访问,所以不依赖字典键的枚举顺序。

不要仅根据第一行的值推断列类型。示例中第一行的 r_z_top50cap 是 null,第二行却有数值,应根据字段定义将整列设为 DOUBLE。

如果接口可能缺少字段、返回嵌套对象或改变日期格式,需要在写入前补充校验。日期解析后也应检查结果是否为空,避免把格式错误当作正常缺失值。对于较大的响应,可以按列收集为有类型的向量后批量写入;逐行写法适合先解决示例中的转换和空值问题。

备注:内容仅供参考。