如何在Python的psycopg2中获取DELETE语句的删除行数?
在Python中用psycopg2获取DELETE命令的删除行数
错误原因
你遇到的psycopg2.ProgrammingError: no results to fetch错误,是因为DELETE属于数据修改语句,不会返回结果集,强行调用fetchone()或fetchall()自然会报错——这两个方法只适用于SELECT这类返回结果集的查询。
正确解决方案:利用cursor.rowcount属性
psycopg2的cursor对象执行DELETE/INSERT/UPDATE后,rowcount属性会直接返回本次操作影响的行数,完全不需要提前执行SELECT count(*)。
1. 修改现有qexe函数
调整函数逻辑,当不需要fetch结果集时,返回rowcount:
def qexe(conn, query, fetch_type=None): cursor = conn.cursor() cursor.execute(query) result = None if fetch_type is not None: if fetch_type == 'fetchall': result = cursor.fetchall() elif fetch_type == 'fetchone': result = cursor.fetchone() else: raise Exception(f"Invalid arg fetch_type: {fetch_type}") else: # 针对DELETE/INSERT/UPDATE,返回操作影响的行数 result = cursor.rowcount cursor.close() return result
2. 安全执行DELETE并获取行数
注意:不要用字符串format拼接SQL,这会导致SQL注入风险。改用psycopg2的参数化查询:
# 使用%s作为占位符(psycopg2的标准参数占位符) qq = """DELETE FROM INV WHERE ITEM_ID = %s;""" item = '123abc' # 执行DELETE,fetch_type传None即可获取删除行数 deleted_count = qexe(conn, qq, None)
3. 优化函数:支持参数化查询(推荐)
为了彻底避免SQL注入,修改函数支持传入参数:
def qexe(conn, query, fetch_type=None, params=None): cursor = conn.cursor() # 有参数时用参数化执行,无参数直接执行 if params: cursor.execute(query, params) else: cursor.execute(query) result = None if fetch_type is not None: if fetch_type == 'fetchall': result = cursor.fetchall() elif fetch_type == 'fetchone': result = cursor.fetchone() else: raise Exception(f"Invalid arg fetch_type: {fetch_type}") else: result = cursor.rowcount cursor.close() return result
使用示例:
qq = """DELETE FROM INV WHERE ITEM_ID = %s;""" item = '123abc' # 传入参数元组,安全执行并获取删除行数 deleted_count = qexe(conn, qq, None, (item,)) print(f"成功删除 {deleted_count} 条记录")
关键说明
rowcount属性对INSERT、UPDATE、DELETE操作都有效,返回实际影响的行数- 参数化查询是psycopg2推荐的写法,能有效防止SQL注入,同时自动处理字符串转义问题
内容的提问来源于stack exchange,提问作者symchiladas
相关产品推荐
相关产品推荐

