You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Presto环境下Spark SQL timestamp转string调用get_spark_df报错

问题排查思路
  • 先查日期合法性:公历6月是小月,满算只有30天,你代码里写的end_date = '2019-06-31'、给出的时间样例2019-06-31 19:00:00本身就是非法日期值。从报错栈可以看到SQL是下推到Presto引擎执行的,Presto解析到非法日期会直接抛出执行异常,这是最高概率的触发原因。
  • 再查SQL语法兼容性:get_spark_df通过JDBC连接拉数时,传入的子查询是直接在底层数据源(这里是Presto)执行,不是Spark原生执行。你写的date_format(xxx, '%Y%m%d')是Spark/MySQL的格式化语法,Presto的date_format遵循Java DateTimeFormatter规范,格式符要用yyyyMMdd,格式符不匹配会直接导致执行失败。
  • 最后查过滤逻辑合理性:你在WHERE条件里对timestamp字段套函数转成INT再比较,一方面会让底层引擎无法命中时间字段的索引,全表扫描性能极差;另一方面如果字段里存在非法时间脏数据,转换过程中碰到坏值就会直接中断任务,只要表中有一条脏数据整个任务就会失败。
可行解决方案

优先选适配下推逻辑的写法,性能最好:

# 第一步先修正非法日期值
start_date = '2019-06-15'
end_date = '2019-06-30'

records = QaasHook.get_spark_df("""
    (SELECT 
        name,
        date_format(startdt, 'yyyyMMdd') AS stdt,
        cast(amnt AS DOUBLE) AS amount,
        date_format(enddt, 'yyyyMMdd') AS endt
    FROM table_1
    -- 不要对字段套函数做比较,直接用时间范围过滤,支持索引命中,也避免转换脏数据报错
    WHERE startdt >= CAST('{st_dt}' AS TIMESTAMP)
      AND enddt < CAST('{end_dt}' AS TIMESTAMP) + INTERVAL '1' DAY
    )
""".format(
    st_dt = start_date,
    end_dt = end_date
))

如果表中确实存在类似6月31日的脏时间数据,可以把cast换成try_cast,转换失败的脏数据会返回null,再加一层is not null过滤即可。

如果不想反复适配不同引擎的SQL语法差异,可以把原始时间字段拉到Spark层再做格式化,完全规避下推语法兼容问题:

start_date = '2019-06-15'
end_date = '2019-06-30'

# 下推的SQL只做原始数据拉取和范围过滤,不做格式化
records = QaasHook.get_spark_df("""
    (SELECT name, startdt, amnt, enddt
    FROM table_1
    WHERE startdt >= CAST('{st_dt}' AS TIMESTAMP)
      AND enddt < CAST('{end_dt}' AS TIMESTAMP) + INTERVAL '1' DAY
    )
""".format(st_dt = start_date, end_dt = end_date))

# 所有格式化、类型转换逻辑在Spark层执行,用Spark原生语法,不存在兼容问题
from pyspark.sql import functions as F
result = records.select(
    F.col('name'),
    F.date_format(F.col('startdt'), 'yyyyMMdd').alias('stdt'),
    F.col('amnt').cast('DOUBLE').alias('amount'),
    F.date_format(F.col('enddt'), 'yyyyMMdd').alias('endt')
)

内容的提问来源于stack exchange,提问作者Tahir Zamaan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 02:21:18