背景
今天在跑一个Flink Table Api 实现的从Hive到Kafka的数据迁移的ETL任务的时候,产生了莫名其妙的错误。
有一个表假设表名为 table1,存放的是日志数据,表中有一个字段 localtime,是代表日志上报的时间戳,是number类型的。sql为 ” select localtime from table1 “,然后再用localtime去做一些转换操作,然后就报了错, java.lang.NumberFormatException,转换异常。
问题分析
数据异常
最开始的时候,一直是以为在这个表中,有脏数据,比如传入了未经转换的时间数据进去,因为报错的信息是说下面这种字符串无法转换,所以就去hive里面去查询,然而并没有找到类似的数据。
1 | 18:16:35.547 |
对比原始数据和flink查出的row数据
查出hive里面的原始数据,然后在打印出flink的row对象,一个个字段对比,发现了端倪。在经过对比后,发现所有的数据都是一致的,唯独这个localtime这一列不同,而且经过时间戳转换后发现,下面的时间和上面的时间完全没有任何联系。
后来定睛一看,下面的事件竟然和当前的时间一致,wtf,
“这是一个函数,返回当前时间!”
请看这个链接 Apache Flink 1.12-SNAPSHOT Documentation: SQL ,localtime为保留字,Apache Flink 1.8 Documentation: Built-In Functions 这个网页上可以看到具体的函数定义。
问题解决
既然是关键字,所以肯定不能直接写localtime,但是表里的字段已经定了,肯定不能轻易改的,所以加个转义就好了,类似下面的sql。
1 | select `localtime` from table1 |
总结
在建表建库的时候,坚决避免使用可能是保留字的词语,比如 local、time、timestamp、schema这些词,一个好的实践可以在表格字段前面加一些前缀,比如 t_table, c_name 等。