pymysql 关于带参的正则查询问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
gossip
V2EX    Python

pymysql 关于带参的正则查询问题

  •  
  •   gossip 2021-12-15 11:24:07 +08:00 2627 次点击
    这是一个创建于 1426 天前的主题,其中的信息可能已经有所发展或是发生改变。
    有个商品表,我打算通过品名查询,但考虑下这种商品名很乱,势必要用正则来取:
    +----+---------------------------------------+
    | id | name |
    +----+---------------------------------------+
    | 1 | r510vc 15.6 英寸笔记本 |
    | 2 | y400n 14.0 英寸笔记本电脑 |
    | 3 | g150th 15.6 英寸游戏本 |
    | 4 | x550cc 15.6 英寸笔记本 |
    | 5 | x240 超级本 |
    | 6 | u330p 13.3 英寸超级本 |
    | 7 | svp13226scb 触控超级本 |
    | 8 | ipad mini 7.9 英寸平板电脑 |
    | 9 | ipad air 9.7 英寸平板电脑 |
    | 10 | ipad mini 配备 retina 显示屏 |
    | 11 | ideacentre c340 20 英寸一体电脑 |
    | 12 | vostro 3800-r1206 台式电脑 |
    | 13 | imac me086ch/a 21.5 英寸一体电脑 |
    | 14 | at7-7414lp 台式电脑 linux ) |
    | 15 | z220sff f4f06pa 工作站 |
    | 16 | poweredge ii 服务器 |
    | 17 | mac pro 专业级台式电脑 |
    | 18 | hmz-t3w 头戴显示设备 |
    | 19 | 商务双肩背包 |
    | 20 | x3250 m4 机架式服务器 |
    | 21 | 商务双肩背包 |
    +----+---------------------------------------+

    比如输入电脑,就显示含有电脑关键字的。于是我写了个查询的类,下面定义一个依据名称查询的方法:

    def search_by_name(self):
    goods_name = input('请输入您要查询的商品名:')
    # sql_command = 'select * from goods where name regexp ".*%s.*"' % goods_name
    # self.execute_sql_command(sql_command)
    #self.cursor.execute('select * from goods where name regexp ".*%s.*"',[goods_name,])
    sql = 'select * from goods where name=%s'
    paras = (goods_name,)
    self.cursor.execute(sql,paras)
    for item in self.cursor.fetchall():
    print(item)

    1.被注释掉的 self.cursor.execute('select * from goods where name regexp ".*%s.*"',[goods_name,])一句是我想达到的目标,但是发现不成功

    于是我猜想可能是正则语句太复杂了?上面有一重引号,导致解析时候发生了错误
    2.为了验证呢,于是写了
    sql = 'select * from goods where name=%s'
    paras = (goods_name,)
    self.cursor.execute(sql,paras)

    这三行没问题,没有用正则,只是普通参数化查询,是可以成功的。
    3.另外非参数化的构造 sql 语句再执行的方法,也能把这个正则查询跑出来,但是会有 sql 注入问题(也就是上面被注释掉的前两行的方法)

    因为是 python 初学者,这个问题应该在前端做规则限制吧。但是还是想知道应该怎么写这种带参的正则查询呢?
    7 条回复    2021-12-16 14:53:13 +08:00
    ErenJaeger
        1
    ErenJaeger  
       2021-12-15 13:59:15 +08:00
    MySQL 正则还真没用过,可以用模糊查询 like
    peonone
        2
    peonone  
       2021-12-15 15:41:25 +08:00   1
    试试
    self.cursor.execute('select * from goods where name regexp %s',[f".*{goods_name}.*",])
    gossip
        3
    gossip  
    OP
       2021-12-15 15:55:26 +08:00
    @peonone 正解了,想问下大佬,这个问题出在哪了呀,为啥里面有双引号就不行呢?
    另外您的写法从哪里看到的,我谷歌了一上午没找到好的方法
    dayeye2006199
        4
    dayeye2006199  
       2021-12-16 03:44:20 +08:00
    您这自己拼 SQL ,眼看着要被注入攻击的感觉;用 prepared statement 把
    peonone
        5
    peonone  
       2021-12-16 11:26:47 +08:00   1
    @gossip 在 SQL 字符串里%s 需要是一个完整的参数值代位符,".*%s.*"这样是不行的。
    我也没找到相关的文档,从我的经验来的:)


    @dayeye2006199 只有被注释的前两行是拼 SQL 的方式,LZ 想解决的问题就是在使用 prepared statement 了。
    但还是要注意会把用户输入的内容当作正则来处理,比如用户输入".*",会匹配任意字符
    gossip
        6
    gossip  
    OP
       2021-12-16 12:09:22 +08:00
    @peonone 感谢啦,您说得没错,觉得这个问题这么解决还不是办法。不过也是没接触过前端,写了个增删改查 sql 的小程序练练手,只有后端的 python 代码。本来想用查询先都把结果干出来,然后 python 对结果进行正则的,后来想了下,觉得这样效率不高,还是放在数据库端了在查询的时候做了匹配。

    不知道真的生产环境下该怎么处理这种问题呢?
    peonone
        7
    peonone  
       2021-12-16 14:53:13 +08:00
    真实环境下这种场景不会使用正则去查询数据库的,效率太低,需要扫描整个表,对每行的商品名做正则匹配,IO 和 CPU 消耗都很高,一种解决办法是使用检索引擎,比如 ElasticSearch ,MySQL 也有全文检索功能 https://dev.mysql.com/doc/refman/8.0/en/fulltext-search.html ,可以用来实现个简单原型试试。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     931 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 20:42 PVG 04:42 LAX 12:42 JFK 15:42
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86