python 2.7 和 MySQLdb 的动态 LIKE 查询

Dynamic LIKE queries with python 2.7 and MySQLdb

据我了解,SQL 注入通常是不好的。这很好,因为如 PEP 249 中所述,您可以使用占位符来防止大多数通用注入。但是我没有看到任何关于如何进行涉及 LIKE 动态查询的内容。

我的具体情况是我有一个 ajax 调用,即 运行 对名称字段的输入更改。结果是我的查询结果被过滤 WHERE table.name LIKE name_var 作为一个简单的表示。显然,直接将 name_var 代入查询是非常危险的,你们中的一些人甚至可能因此而受到轻微打击。但是我如何使它安全和动态呢?我是否构建自己的解析器? MySQLdb 是否有一些内置功能也可以处理这个问题?我似乎找不到太多有用的信息,所以我很感激任何帮助。

是的,我的SQLdb 可以做到这一点。

sql = """SELECT ... WHERE t.name LIKE %s"""
cur = cnx.cursor(prepared=True)
cur.execute(sql, (name_var,))

如果需要通配符以便搜索子字符串,可以在 SQL 表达式中执行此操作:

sql = """SELECT ... WHERE t.name LIKE CONCAT('%', %s, '%')"""
cur = cnx.cursor(prepared=True)
cur.execute(sql, (name_var,))

或者您可以在将其作为参数传递之前对 Python 变量执行此操作:

sql = """SELECT ... WHERE t.name LIKE %s"""
cur = cnx.cursor(prepared=True)
name_var_with_wildcards = '%{0}%'.format(name_var)
cur.execute(sql, (name_var_with_wildcards,))

如果您的 name_var 可能包含文字 LIKE 通配符 %_,您需要转义它们:

sql = """SELECT ... WHERE t.name LIKE CONCAT('%', %s, '%')"""
cur = cnx.cursor(prepared=True)
name_var_escaped = re.sub(r'([_%])', r'\', name_var)
cur.execute(sql, (name_var_escaped,))