如何在循环执行的Presto SQL查询中使用Python日期变量?
解决Python构造Presto SQL时变量嵌入的KeyError问题
你遇到的问题是:直接在SQL字符串中写变量名x、y,Python不会自动将其替换为实际的日期值;若错误使用.format()方法(比如字符串里写了{x}却未通过关键字参数传递对应值),就会触发KeyError。
下面是几种可行的解决方式,同时要注意把Python的日期对象转换成Presto能识别的字符串格式(比如YYYY-MM-DD):
方法1:使用f-string(Python 3.6+ 推荐)
f-string是最简洁直观的方式,直接在字符串前加f,并用{}包裹变量,还能在内部完成日期格式转换:
from datetime import datetime import rrule x = datetime.strptime('12-10-22', '%d-%m-%y').date() y = datetime.strptime('13-10-22', '%d-%m-%y').date() # 假设nextProcStart和nextProcEnd已定义 for dt in rrule.rrule(rrule.HOURLY, dtstart=nextProcStart, until=nextProcEnd): # 将日期对象转为Presto兼容的字符串格式 sql_query = f"SELECT SUM(sales) FROM a WHERE date between '{x.strftime('%Y-%m-%d')}' and '{y.strftime('%Y-%m-%d')}'" # 执行查询的代码...
方法2:使用str.format()方法
如果需要兼容更低版本的Python,可以用.format(),注意占位符的正确使用:
from datetime import datetime import rrule x = datetime.strptime('12-10-22', '%d-%m-%y').date() y = datetime.strptime('13-10-22', '%d-%m-%y').date() x_str = x.strftime('%Y-%m-%d') y_str = y.strftime('%Y-%m-%d') for dt in rrule.rrule(rrule.HOURLY, dtstart=nextProcStart, until=nextProcEnd): sql_query = "SELECT SUM(sales) FROM a WHERE date between '{}' and '{}'".format(x_str, y_str) # 或者用命名占位符更清晰 # sql_query = "SELECT SUM(sales) FROM a WHERE date between '{start_date}' and '{end_date}'".format(start_date=x_str, end_date=y_str) # 执行查询的代码...
注意事项
- 必须将Python的
date/datetime对象转换为字符串,因为Presto无法直接识别Python的日期对象,推荐用strftime('%Y-%m-%d')或者带时间的%Y-%m-%d %H:%M:%S格式,匹配你的表中date字段的类型。 - 若变量来自不可信输入,要警惕SQL注入风险,建议使用参数化查询(不同Presto客户端库可能支持参数绑定,比如
pyhive的execute方法可传参数)。
内容的提问来源于stack exchange,提问作者Garrett Kochner
相关产品推荐
相关产品推荐

