Python中支持参数绑定的主流驱动包括sqlite3、psycopg2、mysql-connector-python和pymysql,它们对接数据库预编译机制;而MySQLdb等旧驱动仅做字符串拼接,不防注入。

Python中哪些数据库驱动支持参数绑定
不是所有Python数据库驱动都原生支持安全的参数绑定,关键看底层是否对接了数据库的预编译机制。主流驱动里,sqlite3、psycopg2(PostgreSQL)、mysql-connector-python 和 pymysql 都支持;但像早期的 MySQLdb(已停更)或某些轻量封装库可能只做字符串拼接,表面用 %s 却不防注入。
验证方法很简单:查文档确认是否明确写了“supports parameterized queries”或“uses server-side prepared statements”,再看示例是否用 cursor.execute(sql, params) 形式——如果参数是单独传入、没进SQL字符串,基本可靠。
用错占位符会导致参数绑定失效
不同驱动对占位符语法要求不同,混用会直接退化成字符串拼接。比如:
-
sqlite3只认?或命名格式:name,写%s会被当成普通字符串字面量 -
psycopg2只接受%s(注意是%s,不是%d或%f),且必须严格按顺序传参 -
pymysql支持%s,但不支持%(name)s这种命名方式(除非显式开启)
典型错误:cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,)) 在 sqlite3 中不会报错,但 %s 被当作文本处理,user_id 的值被直接拼进SQL,完全失去防护作用。
立即学习“Python免费学习笔记(深入)”;
动态列名/表名不能用参数绑定
参数绑定只适用于值(value),不适用于标识符(identifier)——比如列名、表名、ORDER BY 字段、LIMIT 数值等。这些地方必须提前白名单校验或正则过滤,不能靠参数占位。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
例如这段代码是危险的:
sql = "SELECT * FROM users ORDER BY ? LIMIT ?" cursor.execute(sql, (sort_column, limit_num)) # ❌ sort_column 不会被绑定,直接拼入
正确做法是:
- 列名用白名单:
if sort_column not in ['name', 'email', 'created_at']: raise ValueError - LIMIT 数值转整型后格式化:
sql = f"SELECT * FROM users ORDER BY {safe_column} LIMIT {int(limit_num)}"
ORM里的参数绑定容易被绕过
Django ORM、SQLAlchemy 默认使用参数绑定,但开发者常在查询中混入 raw()、text() 或字符串格式化,导致防线失效。
常见陷阱:
- Django:
User.objects.extra(where=["name = '%s'" % user_input])—— 手动拼接,绕过所有保护 - SQLAlchemy:
session.execute(text("SELECT * FROM users WHERE name = '" + name + "'"))—— 直接拼接字符串 - 即使用了
text(),也必须配params=...:text("SELECT * FROM users WHERE name = :name")+params={"name": user_input}
真正安全的边界在于:只要SQL字符串里出现用户输入内容,不管是不是用 f""、% 还是 + 拼的,就已经脱离参数绑定保护范围。
参数绑定本身很简单,难的是保持全程不“漏出”SQL字符串拼接。最易忽略的点是:日志打印SQL时手动拼接、条件分支里混用不同驱动语法、以及把参数绑定当成万能盾牌而忽略标识符校验。

















