Python安全操作PostgreSQL查询方法
本篇文章主要是结合我之前面试的各种经历和实战开发中遇到的问题解决经验整理的,希望这篇《Python安全执行PostgreSQL查询指南》对你有很大帮助!欢迎收藏,分享给更多的需要的朋友学习~

本文详细介绍了在Python中使用`psycopg2`库与PostgreSQL数据库交互时,如何安全有效地将Python变量嵌入到SQL查询语句中。通过避免直接字符串拼接,我们将重点讲解使用SQL占位符(`%s`)和`execute()`方法的参数化查询机制,这不仅能解决常见的`TypeError`,更能有效防范SQL注入攻击,提升代码的健壮性和安全性。
引言:在Python中执行带变量的SQL查询
在开发数据库驱动的Python应用时,经常需要根据程序运行时的数据动态构建SQL查询。例如,根据用户输入查询特定记录,或者更新某个字段的值。初学者常犯的一个错误是直接将Python变量拼接到SQL字符串中,这不仅可能导致语法错误或运行时异常,更重要的是,它会为SQL注入攻击打开大门,严重威胁应用程序的安全性。
本教程将以psycopg2库为例,演示如何在Python中正确且安全地使用变量执行PostgreSQL查询。
错误的实践:直接拼接变量
让我们首先看看一个常见的错误示例。假设我们想根据一个Python变量inputed_email查询用户的密码:
import psycopg2
inputed_email = "test@example.com" # 假设这是从用户输入获取的变量
conn = None
cur = None
try:
conn = psycopg2.connect("dbname=postgres user=postgres password=postgres")
cur = conn.cursor()
# 错误的用法:直接将变量作为execute的独立参数,或进行字符串拼接
# cur.execute("SELECT password FROM user WHERE email = ", inputed_email, ";")
# 这种方式会导致 TypeError: function takes at most 2 arguments (3 given)
# 即使使用字符串拼接,如 f"SELECT password FROM user WHERE email = '{inputed_email}';"
# 也存在SQL注入风险且易出错
print("尝试执行查询...")
# 假设这里是错误的代码,为了演示问题,我们不会运行它
# cur.execute("SELECT password FROM user WHERE email = ",inputed_email,";")
# print(cur.fetchone())
except TypeError as e:
print(f"捕获到错误: {e}")
print("错误提示:execute() 函数最多接受两个参数,但您提供了三个。")
except Exception as e:
print(f"发生其他错误: {e}")
finally:
if cur:
cur.close()
if conn:
conn.close()
print("数据库连接已关闭。")上述代码中,cur.execute("SELECT password FROM user WHERE email = ", inputed_email, ";") 尝试将SQL语句、变量和分号作为三个独立的参数传递给execute()函数。然而,psycopg2的execute()方法最多只接受两个参数:SQL查询字符串和可选的参数序列(用于占位符)。因此,这会导致TypeError: function takes at most 2 arguments (3 given)。
即使我们尝试通过Python的f-string或字符串连接来直接构建SQL,例如 cur.execute(f"SELECT password FROM user WHERE email = '{inputed_email}';"),虽然解决了参数数量的问题,但这是一种非常危险的做法,因为它容易受到SQL注入攻击。
正确的实践:使用占位符进行参数化查询
psycopg2(以及大多数Python数据库API)提供了一种安全且推荐的方式来处理变量:参数化查询。其核心思想是在SQL语句中使用占位符,然后将变量的值作为单独的参数传递给execute()方法。psycopg2会负责正确地转义这些值,防止SQL注入。
对于psycopg2,标准的占位符是 %s。
单个变量的参数化查询
当查询中只有一个变量时,我们这样使用:
import psycopg2
inputed_email = "test@example.com" # 假设这是从用户输入获取的变量
conn = None
cur = None
try:
conn = psycopg2.connect("dbname=postgres user=postgres password=postgres")
cur = conn.cursor()
# 正确的用法:使用 %s 占位符,并将变量作为 execute() 的第二个参数(一个列表或元组)
sql_query = "SELECT password FROM public.user WHERE email = %s" # 注意:这里移除了末尾的分号,通常不是必需的
cur.execute(sql_query, [inputed_email]) # 第二个参数必须是可迭代对象(如列表或元组)
result = cur.fetchone()
if result:
print(f"找到用户密码: {result[0]}")
else:
print(f"未找到邮箱为 '{inputed_email}' 的用户。")
conn.commit() # 对于SELECT语句通常不需要commit,但对于INSERT/UPDATE/DELETE是必需的
except psycopg2.Error as e:
print(f"数据库操作错误: {e}")
if conn:
conn.rollback() # 发生错误时回滚事务
except Exception as e:
print(f"发生其他错误: {e}")
finally:
if cur:
cur.close()
if conn:
conn.close()
print("数据库连接已关闭。")关键点解释:
- 占位符 %s: 在SQL查询字符串中,任何你想插入变量值的地方,都用 %s 代替。
- execute() 的第二个参数: execute() 方法的第二个参数必须是一个可迭代对象(如列表或元组),其中包含按顺序对应占位符的值。即使只有一个值,也必须将其放在列表或元组中,例如 [inputed_email]。
多个变量的参数化查询
如果查询中需要使用多个变量,execute() 方法的第二个参数就包含相应数量的变量,顺序与SQL语句中的 %s 占位符一致。
import psycopg2
user_email = "jane.doe@example.com"
user_lastname = "Doe"
conn = None
cur = None
try:
conn = psycopg2.connect("dbname=postgres user=postgres password=postgres")
cur = conn.cursor()
# 多个变量的参数化查询
sql_query = "SELECT firstname, password FROM public.user WHERE email = %s AND lastname = %s"
cur.execute(sql_query, (user_email, user_lastname)) # 可以使用元组或列表
result = cur.fetchone()
if result:
print(f"找到用户: {result[0]}, 密码: {result[1]}")
else:
print(f"未找到邮箱为 '{user_email}' 且姓氏为 '{user_lastname}' 的用户。")
conn.commit()
except psycopg2.Error as e:
print(f"数据库操作错误: {e}")
if conn:
conn.rollback()
except Exception as e:
print(f"发生其他错误: {e}")
finally:
if cur:
cur.close()
if conn:
conn.close()
print("数据库连接已关闭。")注意事项与最佳实践
- SQL注入防护: 参数化查询是防止SQL注入攻击的黄金法则。psycopg2会自动转义传递给占位符的所有值,确保它们被视为数据而不是可执行的SQL代码。
- execute() 参数类型: 始终记住,execute() 的第二个参数必须是一个可迭代对象(列表或元组),即使只有一个变量。
- SQL语句末尾的分号: 在psycopg2中,SQL语句末尾的分号通常不是必需的,并且在某些情况下可能会导致问题。建议省略它,除非数据库要求或你正在执行多个语句。
- 事务管理: 对于INSERT、UPDATE、DELETE等修改数据的操作,务必在操作成功后调用 conn.commit() 来保存更改。如果发生错误,应调用 conn.rollback() 来撤销未提交的更改。对于SELECT操作,通常不需要commit。
- 资源管理: 始终确保在操作完成后关闭游标(cur.close())和数据库连接(conn.close()),以释放数据库资源。使用 try...except...finally 块是实现这一点的标准模式。
- 错误处理: 捕获psycopg2.Error异常可以更具体地处理数据库相关的错误。
总结
在Python中使用psycopg2执行PostgreSQL查询并嵌入变量时,核心原则是采用参数化查询。通过在SQL语句中使用%s占位符,并将变量值作为execute()方法的第二个参数(一个列表或元组)传递,我们不仅能避免TypeError等常见错误,更能有效地防止SQL注入攻击,从而编写出更安全、更健壮的数据库交互代码。遵循这些最佳实践,将大大提高您Python数据库应用的可靠性。
今天关于《Python安全操作PostgreSQL查询方法》的内容就介绍到这里了,是不是学起来一目了然!想要了解更多关于的内容请关注golang学习网公众号!
JavaScript位运算性能优化与实战案例
- 上一篇
- JavaScript位运算性能优化与实战案例
- 下一篇
- PPT字体批量修改技巧与方法
-
- 文章 · python教程 | 2小时前 | Python 文件名
- Python快速查找文件名方法大全
- 235浏览 收藏
-
- 文章 · python教程 | 2小时前 |
- Python中IOError与OSError区别详解
- 311浏览 收藏
-
- 文章 · python教程 | 2小时前 |
- Python异常处理如何应对网络请求问题
- 487浏览 收藏
-
- 文章 · python教程 | 3小时前 |
- HSV颜色检测方法及实战技巧
- 282浏览 收藏
-
- 文章 · python教程 | 4小时前 | 字符串对齐 ljust()
- Pythonljust()实现左对齐方法详解
- 447浏览 收藏
-
- 文章 · python教程 | 4小时前 |
- strptime逆过程是strftime格式化时间
- 329浏览 收藏
-
- 文章 · python教程 | 5小时前 |
- PythonSocket多播源IP设置教程
- 144浏览 收藏
-
- 文章 · python教程 | 5小时前 |
- Python多进程池卡死排查方法
- 176浏览 收藏
-
- 文章 · python教程 | 5小时前 |
- OpenCV图像识别深度教程
- 298浏览 收藏
-
- 文章 · python教程 | 5小时前 |
- Python脚本文件格式详解
- 347浏览 收藏
-
- 文章 · python教程 | 7小时前 | Python repr str
- repr与str区别详解及使用场景
- 166浏览 收藏
-
- 文章 · python教程 | 7小时前 |
- Typer参数解析与处理方法详解
- 247浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- ChatExcel酷表
- ChatExcel酷表是由北京大学团队打造的Excel聊天机器人,用自然语言操控表格,简化数据处理,告别繁琐操作,提升工作效率!适用于学生、上班族及政府人员。
- 3259次使用
-
- Any绘本
- 探索Any绘本(anypicturebook.com/zh),一款开源免费的AI绘本创作工具,基于Google Gemini与Flux AI模型,让您轻松创作个性化绘本。适用于家庭、教育、创作等多种场景,零门槛,高自由度,技术透明,本地可控。
- 3473次使用
-
- 可赞AI
- 可赞AI,AI驱动的办公可视化智能工具,助您轻松实现文本与可视化元素高效转化。无论是智能文档生成、多格式文本解析,还是一键生成专业图表、脑图、知识卡片,可赞AI都能让信息处理更清晰高效。覆盖数据汇报、会议纪要、内容营销等全场景,大幅提升办公效率,降低专业门槛,是您提升工作效率的得力助手。
- 3503次使用
-
- 星月写作
- 星月写作是国内首款聚焦中文网络小说创作的AI辅助工具,解决网文作者从构思到变现的全流程痛点。AI扫榜、专属模板、全链路适配,助力新人快速上手,资深作者效率倍增。
- 4615次使用
-
- MagicLight
- MagicLight.ai是全球首款叙事驱动型AI动画视频创作平台,专注于解决从故事想法到完整动画的全流程痛点。它通过自研AI模型,保障角色、风格、场景高度一致性,让零动画经验者也能高效产出专业级叙事内容。广泛适用于独立创作者、动画工作室、教育机构及企业营销,助您轻松实现创意落地与商业化。
- 3878次使用
-
- Flask框架安装技巧:让你的开发更高效
- 2024-01-03 501浏览
-
- Django框架中的并发处理技巧
- 2024-01-22 501浏览
-
- 提升Python包下载速度的方法——正确配置pip的国内源
- 2024-01-17 501浏览
-
- Python与C++:哪个编程语言更适合初学者?
- 2024-03-25 501浏览
-
- 品牌建设技巧
- 2024-04-06 501浏览

