Psycopg2是否支持Extended Query Protocol及使用文档咨询
Psycopg2对Extended Query Protocol的支持结论
Psycopg2 原生完整支持 PostgreSQL 的 Extended Query Protocol(扩展查询协议),无需额外安装插件、修改编译参数或手动开启全局开关。
扩展查询协议是PostgreSQL定义的、将SQL处理拆分为解析(Parse)、绑定参数(Bind)、执行(Execute)、同步(Sync)四个独立步骤的交互模式,相比简单查询协议天然支持参数分离传输、执行计划复用、SQL注入防护等能力,是Psycopg2处理参数化查询的默认实现逻辑。
具体使用方法
日常编写参数化查询的过程中,无需手动切换协议,驱动会自动按照扩展查询协议的流程和服务端交互,常见使用场景如下:
- 基础参数化查询
调用execute()方法时使用%s作为参数占位符,将参数以元组形式作为第二个参数传入即可,驱动会自动将SQL模板和参数分开发送给服务端,全程走扩展查询协议:import psycopg2 conn = psycopg2.connect("dbname=test_db user=postgres password=xxx") cur = conn.cursor() # 参数和SQL模板分离传入 cur.execute( "SELECT id, username FROM user_account WHERE register_time > %s AND user_level = %s", ("2024-01-01", 3) ) result = cur.fetchall() - 预编译语句复用
如果需要重复执行同一条SQL,可以显式创建预编译语句,复用SQL解析结果提升执行效率,驱动会自动维护扩展查询协议的会话状态:# 方式1:原生SQL语法实现预编译 cur.execute("PREPARE query_user (int) AS SELECT id, username FROM user_account WHERE id = $1") # 多次执行无需重复解析SQL结构 for uid in [1001, 1002, 1003, 1004]: cur.execute("EXECUTE query_user(%s)", (uid,)) print(cur.fetchone()) # 方式2:使用内置扩展类自动管理预编译生命周期 from psycopg2.extras import PreparedStatement prep_stmt = PreparedStatement(cur, "SELECT id, username FROM user_account WHERE id = %s") for uid in [1001, 1002, 1003, 1004]: prep_stmt.execute((uid,)) print(prep_stmt.fetchone()) - 批量写入/查询
调用executemany()或psycopg2.extras下的execute_values、execute_batch等批量操作方法时,驱动会基于扩展查询协议优化参数批量传输逻辑,相比循环拼接SQL执行性能提升数倍到数十倍:from psycopg2.extras import execute_values user_list = [ (1001, "zhangsan", 3), (1002, "lisi", 2), (1003, "wangwu", 1) ] execute_values( cur, "INSERT INTO user_account (id, username, user_level) VALUES %s", user_list ) conn.commit()
使用注意事项
- 禁止直接将参数通过f-string、字符串拼接的方式写入SQL语句,这种写法会让驱动直接将拼接后的完整SQL通过简单查询协议发送给服务端,不仅完全无法用到扩展查询协议的能力,还存在严重的SQL注入风险,错误写法示例:
# 错误写法,走简单查询协议,存在注入风险 uid = 1001 cur.execute(f"SELECT * FROM user_account WHERE id = {uid}") - Psycopg2默认会自动管理预编译语句的生命周期,大部分场景下不需要手动调用PREPARE语法,直接写参数化
execute()即可获得扩展查询协议的安全和性能收益。
官方参考文档位置
相关说明可以在Psycopg2官方文档的对应章节查询:
- 核心API章节:
cursor.execute()方法的参数规则说明,明确标注参数会与SQL分离传输,使用扩展查询协议实现 - Extras扩展模块章节:
PreparedStatement类的实现说明,描述了扩展查询协议下预编译语句的交互逻辑 - 常见问题与实现说明章节:关于PostgreSQL协议交互的部分,明确说明参数化查询默认采用Extended Query Protocol实现
内容的提问来源于stack exchange,提问作者Gaurav Jha
相关产品推荐
相关产品推荐

