首页 > 解决方案 > 在 C# 中使用 ParquetSharp 库进行基于行的访问,该库基于 apache-parquet-cpp(箭头)

问题描述

有谁知道如何ParquetSharp执行对镶木地板文件的基于行的读取访问?这是我必须去的地方,但inputStream抛出了一个无法转换为字符串的错误。

using (var buffer = new ResizableBuffer())
{
    using (var reader = new ParquetFileReader(@"C:\Users\X\Documents\X.parquet"))
    {
        using (var inputStream = new BufferReader(buffer))
        {
            using (var readerRow = ParquetFile.CreateRowReader<Tuple>(inputStream))
            {
            }
        }
    }
}

ParquetSharp使用TTuple,但我在任何地方都找不到它的任何定义。

我知道镶木地板是基于列的,所以这不是最有效的阅读方法,但它对我的工作很方便。

问候

标签: c#parquetapache-arrow

解决方案


ParquetSharp 的面向行的 API 使用反射来发现给定行结构或类的公共字段。TTuple只是一个泛型参数,是行类型的占位符。

它适用于自定义结构或类 System.Tuple 和 System.ValueTuple。您可以在https://github.com/G-Research/ParquetSharp/blob/master/csharp.test/TestRowOrientedParquetFile.cs中看到一些示例

以您的示例为例,您将定义预期的行类型:

internal struct MyStruct
{
    public readonly int FirstField;
    public readonly string SecondField;
}

然后在你的方法中的某个地方:

using (var reader = ParquetFile.CreateRowReader<MyStruct>(@"C:\Users\X\Documents\X.parquet"))
{
    /* read rows */
}

尽管我个人更喜欢使用 C# 7 元组,但可以省去一开始就必须给出自己的结构定义的麻烦。唯一的缺点是在编写 Parquet 文件时,ParquetSharp 无法从字段名称自动推断列名称(在内部,System.Tuple 和 System.ValueTuple 都有无聊的字段名称,例如 Item1、Item2 等)。

using (var reader = ParquetFile.CreateRowReader<(int firstField, string secondField)>(@"C:\Users\X\Documents\X.parquet"))
{
    /* read rows */
}

推荐阅读