【发布时间】:2022-01-10 22:25:37
【问题描述】:
我有一个 C# 程序,它接收 Parquet 文件数据流,需要将其模式作为字典输出,其中键作为列名,值作为列类型(作为字符串)。我目前正在使用 Parquet.ParquetReader,但我似乎无法访问已转换/逻辑类型的列,只能访问物理类型。我目前的代码如下,使用 ParquetReader.Schema.Fields:
public Dictionary<string, string> GetSchema(Stream stream)
{
Ensure.ArgIsNotNull(stream, nameof(stream));
Dictionary<string, string> types = new Dictionary<string, string>();
try
{
var parquetOptions = new ParquetOptions { TreatByteArrayAsString = true };
var parquetFile = new ParquetReader(stream, parquetOptions);
var schema = parquetFile.Schema;
Dictionary<string, string> types = new Dictionary<string, string>();
foreach (Parquet.Data.DataField field in schema.Fields)
{
var typeName = TranslateParquetType(field);
types.Add(field.Name, typeName);
}
}
catch(Exception ex)
{
throw new DataSourceReadException(ParquetDataFormat.Instance.Name, ex.MessageEx());
}
}
private string TranslateParquetType(Parquet.Data.DataField dataField)
{
if (field.SchemaType == Parquet.Data.SchemaType.Map ||
field.SchemaType == Parquet.Data.SchemaType.Struct ||
field.SchemaType == Parquet.Data.SchemaType.List)
{
return "nested";
}
switch(field.DataType)
{
case Parquet.Data.DataType.Int16:
return "short";
case Parquet.Data.DataType.Int32:
return "int";
case Parquet.Data.DataType.Int64:
return "long";
}
}
我希望能够区分表示数字的 Int64 列和表示时间戳的 Int64 列。我知道这可以在 Parquet 文件的元数据中指定。但是,我只能在 ParquetReader .Schema 中访问每列的物理类型。
例如,我有一个文件,其架构如下所示(使用 parquet-cli,在括号中您可以看到转换后的/逻辑类型):
required group schema {
optional int32 Int32;
optional int64 Int64;
optional int64 Timestampms (Timestamp(isAdjustedToUTC=true, timeUnit=microseconds, is_from_converted_type=false, force_set_converted_type=false));
}
我将把 Int64 作为第三列的类型添加到我的字典中,尽管我想添加时间戳(根据括号中显示的逻辑/转换类型)。
有没有办法在 C# 中访问 parquet 列的逻辑类型,而不是仅访问物理类型?
【问题讨论】: