Delta Time Travel SQL查询版本报extraneous input '0'错误排查
错误根因
- 版本不匹配:你当前引入的Delta依赖为
io.delta:delta-core_2.12:0.7.0,该版本未支持VERSION AS OF/TIMESTAMP AS OF格式的时间旅行SQL语法,这套语法是Delta 1.0正式发布后才合入SQL解析器的。你写的语句中VERSION关键字无法被低版本解析器识别,会被自动忽略,最终SQL被解析为SELECT * FROM RIDES.YELLOW_TAXI AS OF 0——解析器会把AS识别为表别名定义关键字,将OF作为表的别名,末尾的版本号0就成了多余的非法输入,和你看到的ParseException报错完全吻合。 - 无版本号的语句能运行属于解析误判:执行
SELECT * FROM RIDES.YELLOW_TAXI AS OF时,解析器直接将OF识别为表别名,整条语句等价于普通全表查询,和时间旅行功能没有任何关系,自然不会报错。
修复方案
根据你的需求二选一即可:
方案1:保留现有0.7.0版本,使用适配该版本的时间旅行语法
Delta 0.7.0支持在表名后加@v<版本号>后缀完成版本查询,查询版本0的正确写法:
spark.sql("SELECT * FROM RIDES.YELLOW_TAXI@v0")
如果需要按时间戳查询历史版本,使用@<yyyyMMddHHmmssSSS>格式的时间戳后缀即可,示例:
spark.sql("SELECT * FROM RIDES.YELLOW_TAXI@20210201000000000")
方案2:升级Delta版本使用标准AS OF语法
将SparkSession配置中的Delta依赖升级到1.0及以上版本(注意版本要和你当前使用的Spark版本匹配,例如Spark 3.2对应delta-core 2.0.x,Spark 3.3对应delta-core 2.3.x),升级后即可直接使用你最初写的标准语法:
# 按版本号查询 spark.sql("SELECT * FROM RIDES.YELLOW_TAXI VERSION AS OF 0") # 按时间戳查询 spark.sql("SELECT * FROM RIDES.YELLOW_TAXI TIMESTAMP AS OF '2021-02-01 00:00:00'")
正确性验证
你可以用Delta 0.7.0原生支持的DataFrame API时间旅行写法做结果交叉校验,两种写法返回结果一致即说明查询正确:
# DataFrame API 读取指定版本数据 spark.read.format("delta") \ .option("versionAsOf", 0) \ .load("./output/delta") \ .show()
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

