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

如何在Python的MySQL LIKE查询中正确传入参数?

解决MySQLdb中LIKE查询的参数占位问题

你遇到的问题很典型——MySQL的LIKE查询需要通配符%来实现模糊匹配,但直接用参数占位符时没带上它,导致只能精确匹配;而如果写法不对还会触发ProgrammingError,这是因为MySQLdb用%作为参数占位符,和LIKE的通配符冲突了。下面给你两种安全又有效的解决方式:

方法1:在Python参数中添加通配符%

直接在你的字典d里,给需要模糊匹配的字段值前后加上%,SQL语句保持原样即可。这样既符合参数化查询的规范,又能避免SQL注入风险:

import MySQLdb
import MySQLdb.cursors

cnx = MySQLdb.connect(host = 'localhost', database = 'cb-dev', user = 'root', password = 'root', compress = 1, cursorclass=MySQLdb.cursors.DictCursor)

# 给需要模糊匹配的字段添加通配符%
d= {
    "Date": "2017-09-26",
    "Title": "%software%",  # 前后加%实现模糊匹配
    "Location1": "%USA%",
    "Location2": "%United States%",
    "Location3": "%United States of America%",
    "Competency_user": "App\\Job",
    "Comp1_ID": 482,
    "Comp2_ID": 483, 
    "Comp3_ID": 484,
    "Day_rate_lower": 300,
    "Day_rate_upper": 500,
    "hourly_rate_lower": 30,
    "hourly_rate_upper": 50 
}

# SQL语句保持原来的LIKE %(字段名)s写法
query3 = """SELECT id FROM jobs WHERE Date(jobs.closing_date) >= %(Date)s AND title LIKE %(Title)s AND ( location_name_list LIKE %(Location1)s OR location_name_list LIKE %(Location2)s OR location_name_list LIKE %(Location3)s) AND ( EXISTS (SELECT * FROM competencies INNER JOIN competency_maps ON competencies.id = competency_maps.competency_id WHERE jobs.id = competency_maps.competency_mappable_id AND competency_maps.competency_mappable_type = %(Competency_user)s AND competency_id IN ( %(Comp1_ID)s, %(Comp2_ID)s, %(Comp3_ID)s )) OR ( job_rate BETWEEN %(Day_rate_lower)s AND %(Day_rate_upper)s AND job_type = "day rate" ) OR ( job_rate BETWEEN %(hourly_rate_lower)s AND %(hourly_rate_upper)s AND job_type = "contract rate" ))"""

cursor = cnx.cursor()
cursor.execute(query3,d)
sorted_job_Id = cursor.fetchall()
print(sorted_job_Id)

方法2:在SQL中用CONCAT函数拼接通配符

如果不想修改Python的参数字典,可以直接在SQL语句里用MySQL的CONCAT函数把%和参数拼接起来,这样也能避开占位符和通配符的冲突:

# 字典d保持原样,不需要手动加%
d= {
    "Date": "2017-09-26",
    "Title": "software",
    "Location1": "USA",
    "Location2": "United States",
    "Location3": "United States of America",
    "Competency_user": "App\\Job",
    "Comp1_ID": 482,
    "Comp2_ID": 483, 
    "Comp3_ID": 484,
    "Day_rate_lower": 300,
    "Day_rate_upper": 500,
    "hourly_rate_lower": 30,
    "hourly_rate_upper": 50 
}

# 修改LIKE部分为CONCAT('%', %(字段名)s, '%'),用MySQL函数拼接通配符
query3 = """SELECT id FROM jobs WHERE Date(jobs.closing_date) >= %(Date)s AND title LIKE CONCAT('%%', %(Title)s, '%%') AND ( location_name_list LIKE CONCAT('%%', %(Location1)s, '%%') OR location_name_list LIKE CONCAT('%%', %(Location2)s, '%%') OR location_name_list LIKE CONCAT('%%', %(Location3)s, '%%')) AND ( EXISTS (SELECT * FROM competencies INNER JOIN competency_maps ON competencies.id = competency_maps.competency_id WHERE jobs.id = competency_maps.competency_mappable_id AND competency_maps.competency_mappable_type = %(Competency_user)s AND competency_id IN ( %(Comp1_ID)s, %(Comp2_ID)s, %(Comp3_ID)s )) OR ( job_rate BETWEEN %(Day_rate_lower)s AND %(Day_rate_upper)s AND job_type = "day rate" ) OR ( job_rate BETWEEN %(hourly_rate_lower)s AND %(hourly_rate_upper)s AND job_type = "contract rate" ))"""

cursor = cnx.cursor()
cursor.execute(query3,d)
sorted_job_Id = cursor.fetchall()
print(sorted_job_Id)

为什么之前会报错?

如果你尝试直接在SQL里写LIKE '%%(Title)s%%',MySQLdb会把%%解析成单个%,但这种写法很容易导致参数数量和占位符不匹配,触发ProgrammingError: not enough arguments for format string。上面两种方法都能避免这个问题,而且全程用参数化查询,不会有SQL注入的风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:18:47