0%

一个本应三十秒解决掉的Flink函数名冲突问题

背景

今天在跑一个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,

“这是一个函数,返回当前时间!”

image

请看这个链接 Apache Flink 1.12-SNAPSHOT Documentation: SQL ,localtime为保留字,Apache Flink 1.8 Documentation: Built-In Functions 这个网页上可以看到具体的函数定义。

image

问题解决

既然是关键字,所以肯定不能直接写localtime,但是表里的字段已经定了,肯定不能轻易改的,所以加个转义就好了,类似下面的sql。

1
select `localtime` from table1

总结

在建表建库的时候,坚决避免使用可能是保留字的词语,比如 local、time、timestamp、schema这些词,一个好的实践可以在表格字段前面加一些前缀,比如 t_table, c_name 等。