使用parquet::StreamWriter写入Parquet文件时类型匹配异常问题
解决方案
问题根源是通过Arrow Schema转换得到的Parquet Schema没有设置正确的converted type,而parquet::StreamWriter依赖converted type来匹配输入的C++类型。
方法1:直接构建Parquet原生Schema
跳过Arrow Schema转换,直接用Parquet的Schema构建API创建带正确converted type的Schema:
#include <arrow/api.h> #include <arrow/io/api.h> #include <parquet/stream_writer.h> #include <iostream> int main() { std::shared_ptr<arrow::io::FileOutputStream> outfile; std::shared_ptr<parquet::WriterProperties> props = parquet::WriterProperties::Builder().compression(arrow::Compression::SNAPPY)->build(); std::string path2_to_file{"test_fixed.parquet"}; auto result = arrow::io::FileOutputStream::Open(path2_to_file); if (!result.ok()) { std::cout<<"Result not ok\n"; return 1; } outfile = result.ValueOrDie(); // 直接构建Parquet Schema,明确指定converted type auto group_node = parquet::schema::GroupNode::Make( "schema", parquet::Repetition::REQUIRED, { parquet::schema::PrimitiveNode::Make( "A", parquet::Repetition::REQUIRED, parquet::Type::INT32, parquet::ConvertedType::INT_32), // 必须指定converted type parquet::schema::PrimitiveNode::Make( "B", parquet::Repetition::REQUIRED, parquet::Type::DOUBLE, parquet::ConvertedType::NONE) }); parquet::StreamWriter os{ parquet::ParquetFileWriter::Open(outfile, group_node, props)}; int i = 0; while(i<3) { os << int32_t{12} << double(10.4) << parquet::EndRow; i++; } return 0; }
方法2:修正Arrow到Parquet的转换
如果必须使用Arrow Schema,确保转换后的Parquet Schema包含正确的converted type:
// 在创建WriterProperties时,保留默认配置即可 std::shared_ptr<parquet::WriterProperties> props = parquet::WriterProperties::Builder() .compression(arrow::Compression::SNAPPY) ->build(); // 转换Arrow Schema到Parquet Schema std::shared_ptr<parquet::SchemaDescriptor> parquet_schema; parquet::arrow::ToParquetSchema(schema.get(), *props, &parquet_schema); // 直接获取group_node,无需const_cast auto group_nodes = parquet_schema->group_node()->shared_from_this(); parquet::StreamWriter os{ parquet::ParquetFileWriter::Open(outfile, group_nodes, props)};
关键说明
parquet::StreamWriter的<<操作符依赖Parquet列的converted type匹配C++输入类型,比如INT_32对应int32_t,DOUBLE对应double。- 通过
parquet::arrow::ToParquetSchema转换时,部分整数类型的converted type可能未被自动设置,导致StreamWriter无法识别类型匹配关系。 - 直接构建Parquet原生Schema可以精确控制类型属性,避免转换过程中的隐式问题。
内容的提问来源于stack exchange,提问作者roschach
相关产品推荐
相关产品推荐

