如何使用C++读取Parquet文件中的date32[day]类型数据?
问题:Parquet中date32[day]对应的C++读取类型
背景
我有一个Parquet文件,Schema如下:
- Name: string
- Ident: string
- Date: date32[day]
- EventTimestamp: timestamp[us]
我用以下Python脚本导出了该Schema:
#! /usr/bin/env python3 import pyarrow as pa import pyarrow.parquet as pq import sys schema = pq.read_schema(sys.argv[1]) print(schema)
遇到的问题
我想知道date32[day]对应的C++类型是什么。查资料发现它底层是int32_t,但用该类型读取时抛出错误:
terminate called after throwing an instance of 'parquet::ParquetException' what(): Column converted type mismatch. Column 'Date' has converted type 'DATE' not 'INT_32'
尝试用string类型读取时,也得到错误:
terminate called after throwing an instance of 'parquet::ParquetException' what(): Column physical type mismatch. Column 'Date' has physical type 'INT32' not 'BYTE_ARRAY'
我的C++代码如下:
#include <iostream> #include "arrow/io/file.h" #include "parquet/stream_reader.h" #include "readfile.h" int main(int argc, char **argv) { if (argc < 2) { std::cout << "Usage: " << argv[0] << " <input filename" << std::endl; exit(2); } char *input_filename = argv[1]; std::cout << "Input filename is " << input_filename << std::endl; std::shared_ptr<arrow::io::ReadableFile> infile; PARQUET_ASSIGN_OR_THROW( infile, arrow::io::ReadableFile::Open(input_filename)); parquet::StreamReader os{parquet::ParquetFileReader::Open(infile)}; std::string name; std::string ident; int32_t date; std::string ts_event_utc; while (!os.eof()) { os >> name >> ident >> date >> ts_event_utc >> parquet::EndRow; }
解决方案
不能直接用原生int32_t读取,需要使用Arrow库提供的arrow::Date32类型来匹配该列的转换类型标记。date32[day]底层确实是int32_t存储(表示从1970-01-01起的天数),但必须通过对应Arrow类型来读取才能通过类型校验。
修改后的核心代码片段:
// 替换原有的int32_t date; arrow::Date32 date; // 读取时直接使用该类型 while (!os.eof()) { os >> name >> ident >> date >> ts_event_utc >> parquet::EndRow; }
如果需要将arrow::Date32转换为C++原生日期类型(比如std::chrono时间点),可以这样处理:
// 获取底层存储的天数数值 int32_t days_since_epoch = date.value; // 转换为系统时间点 auto epoch = std::chrono::system_clock::from_time_t(0); auto target_date = epoch + std::chrono::days(days_since_epoch);
另外,对于timestamp[us]列,建议同样使用arrow::Timestamp类型读取,避免用std::string导致的类型不匹配问题。
内容的提问来源于stack exchange,提问作者GSP
相关产品推荐
相关产品推荐

