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

Python使用prestodb传数字列表作为查询参数报类型不匹配错误如何解决

问题原因
  • 报错是因为你直接将元组/列表对象用format拼接进SQL时,生成的IN条件语法不符合Presto要求:你写的ID in ({list_id})拼接后会变成ID in ((1, 2, 3, 4)),多了一层嵌套括号,Presto会把括号内的内容识别为一个ROW类型值,和ID字段的bigint类型不匹配,所以触发类型错误。
  • 直接拼接SQL还存在SQL注入的安全隐患,更推荐使用参数化查询的方式传参。
修复方案

方案1:修改字符串拼接逻辑(仅适用非用户输入的可信参数)

将数字列表处理为逗号分隔的字符串,直接放到IN的括号内,代码修改如下:

import prestodb 
from prestodb import dbapi 
import os 

conn=prestodb.dbapi.connect(
    host=os.environ['aa'],
    port=os.environ['bb'],
    user=os.environ['cc'],
    password=os.environ['dd'],
    catalog='hive'
)

date_start = '2021-10-10'
date_end = '2021-10-15'
list_id = (1,2,3,4)
# 把数字列表转成逗号分隔的字符串
list_id_str = ','.join(map(str, list_id))

sql = '''
SELECT
   * 
FROM
   `table`
WHERE
   DATE BETWEEN '{date_start}'
   AND '{date_end}'
   AND ID in ({list_id})
   '''.format(date_start=date_start,date_end=date_end,list_id=list_id_str)

cur = conn.cursor()
cur.execute(sql)
query_result = cur.fetchall()

拼接后生成的IN条件为ID in (1,2,3,4),符合Presto语法要求。

方案2:使用参数化查询(更安全,推荐)

prestodb的dbapi支持参数化传参,不需要手动拼接字符串,既避免语法错误,也能防止SQL注入:

import prestodb 
from prestodb import dbapi 
import os 

conn=prestodb.dbapi.connect(
    host=os.environ['aa'],
    port=os.environ['bb'],
    user=os.environ['cc'],
    password=os.environ['dd'],
    catalog='hive'
)

date_start = '2021-10-10'
date_end = '2021-10-15'
list_id = (1,2,3,4)

# SQL里用%s作为占位符
sql = '''
SELECT
   * 
FROM
   `table`
WHERE
   DATE BETWEEN %s
   AND %s
   AND ID in %s
'''

cur = conn.cursor()
# 参数按顺序放到execute的第二个参数里
cur.execute(sql, (date_start, date_end, list_id))
query_result = cur.fetchall()

这种方式驱动会自动处理参数类型和格式转换,不需要手动处理括号和引号。

内容的提问来源于stack exchange,提问作者Daniel Vargas Shimamoto

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 02:06:01