SQLAlchemy execute执行含子查询的PostgreSQL语句如何安全传参
问题原因及解决方法
报错由两个可修复的问题叠加导致:
1. SQL语法错误
手写的SQL语句漏写了子查询的闭合右括号,正确的子查询结构应为(SELECT 语句) 别名,你漏写了括号直接接别名sub_q,这是触发语法错误的直接原因。
2. 参数占位符与传入key不匹配
SQL语句中子查询的占位符写为%(table2.type)s,但params字典中对应的key为t2.type,二者名称不一致,即使修复语法问题也会抛出参数缺失异常。
修复后的代码
# 修正SQL语法、统一占位符命名(推荐用下划线代替特殊符号,避免驱动解析异常) sql_stmt = """UPDATE table1 t1 SET min_val = sub_q.min_val FROM (SELECT min(value) as min_val FROM table2 t2 WHERE t2.type = %(t2_type)s) sub_q WHERE t1.person = %(t1_person)s """ params = { "t2_type": 2, "t1_person": 5 } execute(sql_stmt, params)
补充优化方案
如果使用SQLAlchemy 2.0+版本,更推荐用SQLAlchemy核心语法构建查询,可自动处理参数绑定、语法适配,降低手写SQL的出错概率:
from sqlalchemy import select, func, update # 构建子查询 sub_q = select(func.min(table2.c.value).label("min_val")).where(table2.c.type == 2).subquery() # 构建更新语句 update_stmt = update(table1).where(table1.c.person == 5).values(min_val=sub_q.c.min_val) # 执行语句 session.execute(update_stmt) session.commit()
内容的提问来源于stack exchange,提问作者JasminD
相关产品推荐
相关产品推荐

