如何使用pandasql对DataFrame创建参数化查询?
问题描述
我想编写如下查询语句,但不知道parameterA、parameterB、parameterC、parameterD的正确语法替换方式,试了几次都没成功。用硬编码值能让查询正常运行,但用变量/参数就不行。
数据类型说明:
column1 = float column2 = category (基于整数的分类) column3 = datetime
目标查询语句:
query = """ SELECT * FROM df_input WHERE column1 >= parameterA AND column1 <= parameterB AND column2 = parameterC AND column3 > parameterD; """
我尝试创建变量并放入查询,但写法错误:
parameterA = input("parameterA Value?") parameterB = input("parameterB Value?") parameterC = input("parameterC Value?") parameterD = input("parameterD Value?")
输入值符合对应数据类型,请问如何让这些参数在pandasql的SQL代码中生效?
注:我不是查询外部数据库,只用pandasql查询DataFrame,不需要数据库引擎、连接和游标。其实熟悉关系型数据库的话,连接外部系统反而更简单。我正从RDBMS转向用pandas和DataFrame做数据分析,因为熟悉SQL所以想用pandasql,不确定有没有必要,毕竟原生pandas过滤可能更直接,但还是想试试。
解决方法
在pandasql中使用参数有两种常用且安全的方式,可避免直接字符串拼接导致的语法错误或潜在风险:
方式1:使用pandasql的params参数(推荐)
pandasql的sqldf函数支持通过params参数传递变量,能自动处理数据类型转换,是最稳妥的方法:
from pandasql import sqldf import pandas as pd # 先将输入转换为对应数据类型 parameterA = float(input("parameterA Value?")) parameterB = float(input("parameterB Value?")) parameterC = int(input("parameterC Value?")) parameterD = pd.to_datetime(input("parameterD Value?")) # 编写查询时用`?`作为参数占位符 query = """ SELECT * FROM df_input WHERE column1 >= ? AND column1 <= ? AND column2 = ? AND column3 > ?; """ # 执行查询时传入params参数,按占位符顺序传值 result_df = sqldf(query, params=(parameterA, parameterB, parameterC, parameterD), env=globals())
方式2:使用Python字符串格式化
如果习惯用字符串拼接,需注意给不同类型参数添加对应格式:
- 数值类型(float、int)直接拼接即可
- datetime类型需要包裹单引号,转换为SQL能识别的字符串格式
from pandasql import sqldf import pandas as pd # 转换输入类型 parameterA = float(input("parameterA Value?")) parameterB = float(input("parameterB Value?")) parameterC = int(input("parameterC Value?")) parameterD = pd.to_datetime(input("parameterD Value?")) # 使用f-string格式化查询语句 query = f""" SELECT * FROM df_input WHERE column1 >= {parameterA} AND column1 <= {parameterB} AND column2 = {parameterC} AND column3 > '{parameterD.strftime('%Y-%m-%d %H:%M:%S')}'; """ # 执行查询 result_df = sqldf(query, env=globals())
关键注意点
- 必须将
input()获取的字符串转换为对应数据类型,因为input()默认返回字符串,直接使用会导致SQL语法错误 - 优先选择
params参数的方式,既能避免语法问题,也能养成规避SQL注入风险的好习惯(即使是本地DataFrame操作) - datetime类型通过字符串格式化时,要转为
YYYY-MM-DD HH:MM:SS这类SQL标准格式
内容的提问来源于stack exchange,提问作者noobie
相关产品推荐
相关产品推荐

