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

如何使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 09:47:14