使用Pandas与SQLAlchemy批量执行SQL时,如何动态提取绑定参数?
识别SQL脚本中的绑定参数并提示用户输入
不用正则表达式,直接利用SQLAlchemy内置的SQL解析能力就能准确提取绑定参数,避免正则误判的问题,具体实现步骤如下:
核心思路
SQLAlchemy的sa.text()对象会自动解析SQL文本中的绑定参数(格式为:param_name),通过其内置属性可以直接获取所有参数名称,无需手动正则匹配。
修正后的完整代码
import sys, os, pandas as pd, re, sqlalchemy as sa os.chdir(sys.argv[1]) # 先判断out目录是否存在,避免重复创建报错 if not os.path.exists("out"): os.mkdir("out") uname = input("Username >>> ") passw = input("Password >>> ") engine = sa.create_engine(f"oracle+cx_oracle://{uname}:{passw}@PROD/?encoding=UTF-8&nencoding=UTF-8") for filename in os.listdir('.'): # 修正正则匹配逻辑,忽略非SQL文件 if not re.match(r".*\.sql", filename): continue print("Executing", filename) with open(filename, "r") as my_file: # 一次性读取SQL内容,避免二次读取时文件指针到末尾 sql_content = ''.join(my_file.readlines()) sql_text = sa.text(sql_content) # 提取所有合法的绑定参数名称 bind_param_names = list(sql_text.compile().params.keys()) # 收集用户输入的参数值 params = {} if bind_param_names: print(f"检测到{len(bind_param_names)}个绑定参数,请输入对应值:") for param in bind_param_names: params[param] = input(f"参数 {param} >>> ") # 传入参数执行查询 df = pd.read_sql(sql_text, engine, params=params) # 将SQL文件名替换为Excel后缀,避免格式错误 output_filename = f"./out/{os.path.splitext(filename)[0]}.xlsx" df.to_excel(output_filename, index=False)
关键说明
- 参数提取准确性:
sql_text.compile().params返回有序字典,键为SQL中定义的绑定参数名称,SQLAlchemy会自动忽略字符串、注释中的类似格式内容,避免正则误判。 - 文件读取优化:原代码两次调用
readlines()会导致第二次读取为空,改为一次性读取内容到变量复用。 - 输出文件修正:将
.sql后缀替换为.xlsx,同时修正to_excel的参数错误,避免把文件名作为工作表名。 - 容错处理:添加目录存在判断,避免重复创建目录报错。
内容的提问来源于stack exchange,提问作者Jakob Lovern
相关产品推荐
相关产品推荐

