parquet StreamReader 为几列提供空白值,并为另一列提供正确值?

问题描述 投票:0回答:1

这就是我使用文档中给出的示例填充镶木地板文件的方式: 有三列 - 日、月和年

  arrow::Int8Builder int8builder;
  int8_t days_raw[15] = {1, 12, 17, 23, 28, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19};
  ARROW_RETURN_NOT_OK(int8builder.AppendValues(days_raw, 15));
  std::shared_ptr<arrow::Array> days;
  ARROW_ASSIGN_OR_RAISE(days, int8builder.Finish());

  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());

  arrow::Int16Builder int16builder;
  int16_t years_raw[15] = {1990, 2000, 1995, 2000, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
                           2002, 2003, 2004, 2015};
  ARROW_RETURN_NOT_OK(int16builder.AppendValues(years_raw, 15));
  std::shared_ptr<arrow::Array> years;
  ARROW_ASSIGN_OR_RAISE(years, int16builder.Finish());

  /* Get a vector of our Arrays */
  std::vector<std::shared_ptr<arrow::Array>> columns = {days, months, years};

  /* Make a schema to initialize the Table with */
  std::shared_ptr<arrow::Field> field_day, field_month, field_year;
  std::shared_ptr<arrow::Schema> schema;

  field_day = arrow::field("Day", arrow::int8());
  field_month = arrow::field("Month", arrow::int8());
  field_year = arrow::field("Year", arrow::int16());

  schema = arrow::schema({field_day, field_month, field_year});
  /* With the schema and data, create a Table */
  std::shared_ptr<arrow::Table> table;
  table = arrow::Table::Make(schema, columns);

  /* Write out test files in CSV, and Parquet for the example to use. */
  std::shared_ptr<arrow::io::FileOutputStream> outfile;

  ARROW_ASSIGN_OR_RAISE(outfile, arrow::io::FileOutputStream::Open("test_in.parquet"));
  PARQUET_THROW_NOT_OK(
      parquet::arrow::WriteTable(*table, arrow::default_memory_pool(), outfile, 10));

这就是我尝试读取和显示以检查文件是否正确填充的方式: 它正确显示最后一个字段“年份”,但日期和月份显示为空白或空格。 我究竟做错了什么?我搜索了一下,但没有得到任何具体信息。

PARQUET_ASSIGN_OR_THROW(infile, arrow::io::ReadableFile::Open("test_in.parquet"));

parquet::StreamReader stream{parquet::ParquetFileReader::Open(infile)};

int8_t day;
int8_t month;
int16_t year;

while (!stream.eof())
{
  stream >> day >> month >> year >> parquet::EndRow;

  std::cout << "Day=" << day << ", month=" << month << ", year=" << year << std::endl;
}

!!!readDisplayParquetFile:打开文件 test_out.parquet
日=、月=、年=1990
日= ,月=,年=2000
日=、月=、年=1995
日=、月=、年=2000
日=、月=、年=1995
日= 、月=、年=1996
日= , 月= ,年份=1997
。 .

我正在尝试解码所有列的数据以进行打印,但只有一个(最后)列数据得到正确解码。

parquet apache-arrow
1个回答
0
投票

没关系,我已经得到答案了。

对于日和月,int8_t 被插入,但 parquet 不接受,因此它被写入,但值被损坏,因此读取问题。

如果我在插入时将其转换为 int16_t,并在显示时像数组一样使用相同的内容,就像变量“年份”一样,那么它就可以工作。

虽然在他们的页面上提到 Arrow 类型 int8 将转换为 parquet INT32 物理形式,但它可能不会发生,或者有一些额外的步骤。 https://arrow.apache.org/docs/cpp/parquet.html#parquet-writer-properties

© www.soinside.com 2019 - 2024. All rights reserved.