如何在YAML中配置供Python 2.7使用的动态填充SQL查询
安全实现YAML存储动态SQL查询(Python 2.7)
你的核心问题在于错误地在YAML里写Python字符串拼接语法,这不仅无法被解析,还存在严重的SQL注入风险。下面是更安全、可复用的实现方案:
1. 优化YAML的查询写法
直接在YAML中使用数据库驱动支持的参数占位符,不要写Python的拼接逻辑。根据你使用的数据库驱动,有两种常用写法:
方式一:位置占位符(兼容大多数驱动)
# queries.yaml get_active_user: "SELECT u.username, u.email from users u WHERE u.status='active' AND id=%s AND u.username=%s"
方式二:命名占位符(可读性更强,适合多参数场景)
如果你的数据库驱动支持(比如MySQLdb),可以用命名占位符:
# queries.yaml get_active_user: "SELECT u.username, u.email from users u WHERE u.status='active' AND id=%(user_id)s AND u.username=%(username)s"
2. Python脚本的正确实现
先安装依赖的PyYAML库(pip install pyyaml),然后加载YAML并安全执行查询:
使用位置占位符的脚本示例
import yaml # 替换成你实际用的数据库驱动,比如MySQLdb、psycopg2等 import MySQLdb # 加载YAML中的查询配置 with open('queries.yaml', 'r') as f: query_config = yaml.safe_load(f) # 假设file是你的数据源(比如CSV行、其他查询结果) for row in file: # 避免和Python内置函数id冲突,重命名变量 user_id = row.id username = row.username # 执行查询时,将参数以元组形式传入execute方法 dbcur.execute(query_config['get_active_user'], (user_id, username)) # 获取并处理查询结果 user_data = dbcur.fetchone() if user_data: print(f"用户名: {user_data[0]}, 邮箱: {user_data[1]}")
使用命名占位符的脚本示例
import yaml import MySQLdb with open('queries.yaml', 'r') as f: query_config = yaml.safe_load(f) for row in file: user_id = row.id username = row.username # 以字典形式传入参数,对应YAML中的命名占位符 dbcur.execute(query_config['get_active_user'], { 'user_id': user_id, 'username': username }) user_data = dbcur.fetchone() # 处理结果...
3. 关键优势说明
- 避免SQL注入:数据库驱动会自动处理参数的转义,杜绝恶意SQL注入风险
- 复用性强:YAML可存储多个查询,比如新增
get_all_active_users,脚本直接调用即可 - 维护成本低:SQL查询和Python代码分离,非开发人员也能修改查询逻辑(需懂SQL)
内容的提问来源于stack exchange,提问作者SamPhoenix
相关产品推荐
相关产品推荐

