Arrow Parquet StreamReader读取部分列返回空值的问题求助
Arrow Parquet StreamReader读取部分列返回空值的问题求助
看起来你遇到的问题很可能是复用int8builder时没有重置状态导致的!我们先拆解下你的代码问题:
你在构建完days数组后,直接用同一个int8builder去追加months_raw的数据,但Arrow的Builder在调用Finish()后,虽然会把内部数据转移到新生成的Array中,但最佳实践是复用前手动重置Builder状态——否则可能导致months数组包含无效数据,或者和days数组的长度/内容不匹配,最终写入Parquet后,读取时就会出现部分列空值的异常。
第一步:修复写入代码
在复用int8builder构建months数组前,调用Reset()方法重置Builder的状态:
// 构建完days数组后,重置builder,确保干净状态 int8builder.Reset(); int8_t months_raw[15] = {1, 3, 5, 7, 1, 2, 12, 4, 5, 6, 7, 8, 9, 10, 11}; ARROW_RETURN_NOT_OK(int8builder.AppendValues(months_raw, 15)); std::shared_ptr<arrow::Array> months; ARROW_ASSIGN_OR_RAISE(months, int8builder.Finish());
这样能保证months数组是从空白状态开始构建的,和days数组长度一致、内容准确。
第二步:验证读取逻辑(可选排查)
如果修复写入后还是有问题,可以换用Arrow原生的TableReader读取文件,先确认文件本身是否正确:
PARQUET_ASSIGN_OR_THROW(infile, arrow::io::ReadableFile::Open("test_in.parquet")); // 使用Arrow TableReader读取 auto parquet_reader = arrow::parquet::ParquetFileReader::Open(infile); auto table_reader = parquet_reader->GetTableReader(); std::shared_ptr<arrow::Table> table; ARROW_ASSIGN_OR_RAISE(table, table_reader->Read()); // 打印列内容验证 auto day_col = table->GetColumnByName("Day"); auto month_col = table->GetColumnByName("Month"); auto year_col = table->GetColumnByName("Year"); std::cout << "Day列值:" << day_col->ToString() << std::endl; std::cout << "Month列值:" << month_col->ToString() << std::endl; std::cout << "Year列值:" << year_col->ToString() << std::endl;
如果这个方式能正确输出Day和Month的值,说明问题出在parquet::StreamReader的使用上,此时可以尝试显式指定读取列的顺序:
// 显式指定要读取的列(匹配schema顺序) stream.SelectColumns({"Day", "Month", "Year"}); while (!stream.eof()) { stream >> day >> month >> year >> parquet::EndRow; std::cout << "Day=" << day << ", month=" << month << ", year=" << year << std::endl; }
总结
最可能的根源是Builder复用未重置导致写入的Parquet文件数据异常,先修复写入代码中的Builder重置问题,再验证读取结果。如果还有问题,用TableReader排查是文件本身的问题还是StreamReader的使用问题。
备注:内容来源于stack exchange,提问作者amitfreeman
相关产品推荐
相关产品推荐

