parquet与schema的那点事
最近做了一个从数据库迁移到parquet报异常的案例,错误如下:
java.lang.IllegalArgumentException:No enum constant org.apache.parquet.schema.OriginalType.nihao total entry:11 java.lang.Enum.valueOf(Unknown Source)
org.apache.parquet.schema.OriginalType.valueOf(OriginalType.java:21)
org.apache.parquet.schema.MessageTypeParser.addPrimitiveType(MessageTypeParser.java:163)
org.apache.parquet.schema.MessageTypeParser.addType(MessageTypeParser.java:112)
org.apache.parquet.schema.MessageTypeParser.addGroupTypeFields(MessageTypeParser.java:100)
org.apache.parquet.schema.MessageTypeParser.parse(MessageTypeParser.java:93)
org.apache.parquet.schema.MessageTypeParser.parseMessageType(MessageTypeParser.java:83)
根据错误内容,很明显就是报No enum constant org.apache.parquet.schema.OriginalType.nihao 的错误。
查看OriginalType的源码定义,支持的type里没有nihao,这就是为什么报错:
https://github.com/apache/parquet-mr/blob/master/parquet-column/src/main/java/org/apache/parquet/schema/OriginalType.java
那么nihao是从哪里来的呢?接下来就要查看数据表结构的shema,schema如下:
name
age
test(nihao)
…
原来nihao来源于test(nihao),那么为什么呢?
继续分析源码:
https://github.com/apache/parquet-mr/blob/master/parquet-column/src/main/java/org/apache/parquet/schema/MessageTypeParser.java
/**
*
* @param input the text representation of the schema to parse
* @return the corresponding object representation
*/
public static MessageType parseMessageType(String input) {
return parse(input);
}
private static MessageType parse(String schemaString) {
Tokenizer st = new Tokenizer(schemaString, " ;{}()\n\t");
原来对schemaString做了parse,new了Tokenizer对象,Tokenizer哪里来的啊?
public Tokenizer(String schemaString, String string) {
st = new StringTokenizer(schemaString, " ,;{}()\n\t=", true);
}
原来来源于StringTokenizer:https://docs.oracle.com/javase/7/docs/api/java/util/StringTokenizer.html#StringTokenizer(java.lang.String,%20java.lang.String,%20boolean)
The set of delimiters (the characters that separate tokens)
,;{}()\n\t=字符就是分隔符啊,分隔符()就是问题的关键,原来如此:
test(nihao)为schema,parseMessageType要parse出type,就是用的分隔符 ,;{}()\n\t=来parse,这里用到的分隔符是(), 由于nihao不是OriginalType中的member,所以报错啊。
解决方法就是避免schema用特殊符号 ,;{}()\n\t=