读取 JSON 文件#

行分隔的 JSON 文件可以作为单个 Arrow 表读取,使用 TableReader 或者使用 StreamingReader 作为 RecordBatch 流式传输。

这两个读取器都需要一个 arrow::io::InputStream 实例,代表输入文件。 可以使用 ReadOptionsParseOptions 和其他参数的组合来自定义其行为。

TableReader#

TableReader 一次性读取整个文件作为 Table。 输入文件中的每个独立 JSON 对象都转换为输出表中的一行。

#include "arrow/json/api.h"

{
   // ...
   arrow::MemoryPool* pool = default_memory_pool();
   std::shared_ptr<arrow::io::InputStream> input = ...;

   auto read_options = arrow::json::ReadOptions::Defaults();
   auto parse_options = arrow::json::ParseOptions::Defaults();

   // Instantiate TableReader from input stream and options
   auto maybe_reader = arrow::json::TableReader::Make(pool, input, read_options, parse_options);
   if (!maybe_reader.ok()) {
      // Handle TableReader instantiation error...
   }
   auto reader = *maybe_reader;

   // Read table from JSON file
   auto maybe_table = reader->Read();
   if (!maybe_table.ok()) {
      // Handle JSON read error
      // (for example a JSON syntax error or failed type conversion)
   }
   auto table = *maybe_table;
}

StreamingReader#

StreamingReader 以大致相等的字节大小的块增量读取文件,每个块产生一个 RecordBatch。 块中的每个独立 JSON 对象都转换为输出批处理中的一行。

所有批处理都遵循一致的 Schema,该 Schema 从第一个加载的批处理派生而来。 或者,可以通过 ParseOptions 传递显式模式。

#include "arrow/json/api.h"

{
   // ...
   auto read_options = arrow::json::ReadOptions::Defaults();
   auto parse_options = arrow::json::ParseOptions::Defaults();

   std::shared_ptr<arrow::io::InputStream> stream;
   auto result = arrow::json::StreamingReader::Make(stream,
                                                    read_options,
                                                    parse_options);
   if (!result.ok()) {
      // Handle instantiation error
   }
   std::shared_ptr<arrow::json::StreamingReader> reader = *result;

   for (arrow::Result<std::shared_ptr<arrow::RecordBatch>> maybe_batch : *reader) {
      if (!maybe_batch.ok()) {
         // Handle read/parse error
      }
      std::shared_ptr<arrow::RecordBatch> batch = *maybe_batch;
      // Operate on each batch...
   }
}

数据类型#

由于 JSON 值是类型化的,因此输出上可能的 Arrow 数据类型取决于输入值类型。 顶级 JSON 值应始终是对象。 顶级对象的字段被认为是 Arrow 数据中的列。 对于 JSON 对象中的每个名称/值对,有两种可能的模式来决定输出数据类型

  • 如果名称在 ParseOptions::explicit_schema 中,则尝试将 JSON 值转换为相应的 Arrow 数据类型;

  • 否则,Arrow 数据类型通过对 JSON 值进行类型推断来确定,依次尝试多种 Arrow 数据类型。

下表显示了这两种模式的可能组合。

从 JSON 到 Arrow 的显式转换#

JSON 值类型

允许的 Arrow 数据类型

Null

任何类型(包括 Null)

数字

所有整数类型、Float32、Float64、Date32、Date64、Time32、Time64

布尔值

布尔值

字符串

Binary、LargeBinary、String、LargeString、Timestamp

数组

列表

对象(嵌套)

结构体

从 JSON 到 Arrow 的隐式类型推断#

JSON 值类型

推断的 Arrow 数据类型(按顺序)

Null

Null,任何其他类型

数字

Int64、Float64

布尔值

布尔值

字符串

Timestamp(具有秒单位)、字符串

数组

列表

对象(嵌套)

结构体