C++开发中如何获取Parquet文件读取结果的行视图
从Parquet读取行视图的实现方案
你提到的ColumnarTableToVector可以满足需求,另外也可以手动从列存结构中按需提取行数据,两种方案分别适配不同的使用场景,以下是具体实现步骤:
前置修正
你现有代码中存在一处逻辑错误:columns_to_tabulate的初始化长度用了this->total_row(总行数),实际应该用总列数,否则会出现列读取不全或者数组越界的问题,修正后代码如下:
std::vector<int> columns_to_tabulate(this->total_columns); for (int idx = 0; idx < this->total_columns; idx++) columns_to_tabulate[idx] = idx;
方案1:使用ColumnarTableToVector批量转换(适合批量读取全量行场景)
如果需要一次性读取当前row group内的所有行并结构化存储,直接用Arrow提供的ColumnarTableToVector方法是最简洁的选择:
- 首先定义和表结构匹配的结构体:
struct User { int64_t id; std::string name; std::string email; std::string phone; bool is_active; };
- 调用转换方法直接生成结构化行数组:
#include <arrow/compute/api_vector.h> // 读取row group得到table之后执行转换 arrow::Result<std::vector<User>> convert_res = arrow::compute::ColumnarTableToVector<User>(*table); if (convert_res.ok()) { std::vector<User> user_rows = convert_res.ValueUnsafe(); // 直接通过下标取目标行 User target_row = user_rows[local_row_num]; // 后续处理target_row即可 }
- 优势:无需手动处理列类型转换、列转行映射,代码维护成本低。
方案2:手动提取目标行(适合仅读取单条/少量行场景)
如果每次只需要读取指定的某一行,不需要转换全量数据,可以直接从列存的Arrow Table中按行号提取对应值,内存开销更低:
// 提取各列的数组(单row group场景下每个列只有一个chunk) auto id_arr = std::static_pointer_cast<arrow::Int64Array>(table->column(0)->chunk(0)); auto name_arr = std::static_pointer_cast<arrow::StringArray>(table->column(1)->chunk(0)); auto email_arr = std::static_pointer_cast<arrow::StringArray>(table->column(2)->chunk(0)); auto phone_arr = std::static_pointer_cast<arrow::StringArray>(table->column(3)->chunk(0)); auto is_active_arr = std::static_pointer_cast<arrow::BooleanArray>(table->column(4)->chunk(0)); // 按local_row_num取值组装行数据 User target_row; target_row.id = id_arr->Value(local_row_num); target_row.name = name_arr->GetString(local_row_num); target_row.email = email_arr->GetString(local_row_num); target_row.phone = phone_arr->GetString(local_row_num); target_row.is_active = is_active_arr->Value(local_row_num);
注意:如果你的列存在多个chunk,需要先计算
local_row_num对应的chunk索引和chunk内偏移,再取值,上述代码适配绝大多数单row group读取的场景。
内容的提问来源于stack exchange,提问作者Shravan40
相关产品推荐
相关产品推荐

