使用xitongsys/parquet-go读取Parquet文件时Schema匹配错误求助
我定义了对应Parquet文件的Go结构体:
type TempoTrace struct { TraceIDText string DurationNano int64 StartTimeUnixNano int64 RS []resourceSpan } type resourceSpan struct { Resource Resource ScopeSpan []ScopeSpan } type Resource struct { ServiceName string }
对应的JSON Schema如下:
{ "Tag":"name=parquet_go_root, repetitiontype=REQUIRED", "Fields":[ { "Tag":"name=TraceIDText, inname=TraceIDText, type=BYTE_ARRAY" }, { "Tag":"name=DurationNano, inname=DurationNano, type=INT64" }, { "Tag":"name=RS, inname=rs, type=LIST, repetitiontype=REQUIRED", "Fields":[ { "Tag":"name=element, repetitiontype=REQUIRED", "Fields":[ { "Tag":"name=Resource, inname=Resource, repetitiontype=REQUIRED", "Fields":[ { "Tag":"name=ServiceName, inname=ServiceName, type=BYTE_ARRAY" } ] } ] } ] } ] }
创建Parquet Reader时出现错误:
Can't create parquet reader [NextRowGroup] Column not found:
Parquet_go_rootRsListElementResourceServiceName
我使用github.com/segmentio/parquet-go时功能正常,但需要支持GCS,因此求助如何为Resource结构体创建正确的Schema。segmentio的实现如下:
type TempoTrace struct { TraceIDText string `parquet:"TraceIDText"` DurationNano int64 `parquet:"DurationNano"` RootServiceName string `parquet:"RootServiceName"` StartTimeUnixNano int64 `parquet:"StartTimeUnixNano"` EndTimeUnixNano int64 `parquet:"EndTimeUnixNano"` RootSpanName string `parquet:"RootSpanName"` RS []resourceSpan `parquet:"rs,list"` } type resourceSpan struct { Resource Resource `parquet:"Resource"` } type Resource struct { ServiceName string `parquet:"ServiceName"` }
报错核心是JSON Schema生成的列名和Parquet文件实际列名不匹配,问题出在嵌套结构的命名规则上。从报错列名Parquet_go_rootRsListElementResourceServiceName能看出,当前Schema生成的路径是Parquet_go_root -> Rs -> list -> element -> Resource -> ServiceName,但实际文件列名需和segmentio生成的一致,调整方式如下:
修正LIST类型字段的命名:
segmentio中RS字段用parquet:"rs,list"标签,说明对应Parquet列名为小写rs,而你的Schema里写的是name=RS,需改成小写name=rs,和标签命名保持一致。统一嵌套结构体字段名大小写:
报错列名里的Rs(大写R)不符合实际,改成小写rs后,Schema生成的列路径会和文件实际列名匹配。
修正后的JSON Schema:
{ "Tag":"name=parquet_go_root, repetitiontype=REQUIRED", "Fields":[ { "Tag":"name=TraceIDText, inname=TraceIDText, type=BYTE_ARRAY" }, { "Tag":"name=DurationNano, inname=DurationNano, type=INT64" }, { "Tag":"name=rs, inname=rs, type=LIST, repetitiontype=REQUIRED", "Fields":[ { "Tag":"name=element, repetitiontype=REQUIRED", "Fields":[ { "Tag":"name=Resource, inname=Resource, repetitiontype=REQUIRED", "Fields":[ { "Tag":"name=ServiceName, inname=ServiceName, type=BYTE_ARRAY" } ] } ] } ] } ] }
额外注意:
- 你的Go结构体中
resourceSpan包含ScopeSpan字段,但当前Schema和segmentio结构体都未处理该字段,如果Parquet文件中存在这个字段,需要在Schema中补充对应定义,否则也可能出现列找不到的问题。 - 所有字段的
name属性必须和segmentio标签里的名称完全一致,Parquet列名区分大小写,拼写、大小写都不能出错。
内容的提问来源于stack exchange,提问作者Silvio Hanky

