You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SQLAlchemy(PostgreSQL)的LIKE '%input%'子句中防止SQL注入?

在SQLAlchemy中安全处理含通配符的LIKE查询

你遇到的这个场景很常见:既要让用户输入的%和_作为普通字符精确匹配,又要彻底避免SQL注入,同时让LIKE查询正常工作。你之前写的代码没生效,问题出在参数占位符的写法上——'%:text%'里的:text会被当成字符串的一部分,SQLAlchemy根本不会把它解析成参数,自然匹配不到预期的行。

下面给你两种SQLAlchemy里的惯用解决方案,都能满足你的需求:

方案一:手动转义通配符+参数化拼接

首先我们需要一个小函数,把用户输入里的PostgreSQL LIKE通配符(%、_)转义成字面量,同时还要转义转义符本身(PostgreSQL默认用\作为转义符):

def escape_like_input(value):
    # 先转义反斜杠,再转义%和_
    return value.replace("\\", "\\\\").replace("%", "\\%").replace("_", "\\_")

然后在查询时,先转义用户输入,再拼接前后的%,直接传给like()方法——SQLAlchemy会自动把整个拼接后的字符串作为安全参数处理:

safe_input = escape_like_input(user_input)
entities = session.query(Entity).filter(Entity.name.like(f"%{safe_input}%")).all()

这样一来,用户输入的%和_会被当成普通字符匹配,同时完全避免了SQL注入风险。

方案二:用SQLAlchemy的func实现SQL层面的拼接

如果你更倾向于在SQL层面处理字符串拼接,可以用SQLAlchemy的func模块调用PostgreSQL的字符串函数,同样先转义用户输入:

from sqlalchemy import func

safe_input = user_input.replace("%", "\\%").replace("_", "\\_")
entities = session.query(Entity).filter(
    Entity.name.like(func.concat("%", safe_input, "%"))
).all()

这种方式和方案一本质上是一样的,只是把字符串拼接的逻辑放到了数据库端执行,同样安全可靠。

再说说你原代码的问题

你之前写的:

entities = session.query(Entity).filter(Entity.name.like('%:text%')) \ 
    .params(text=user_input).all()

这里的'%:text%'是一个完整的字符串字面量,SQLAlchemy会直接把它作为LIKE的匹配模式发送给数据库,:text不会被替换成用户输入的内容——相当于你在找名字里包含:text这个字符串的实体,当然匹配不到预期结果啦。

内容的提问来源于stack exchange,提问作者bdesham

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:12:28