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

PyMySQL中cursor.execute传递字符串参数报错问题求助

问题原因分析

你遇到的这个问题,核心在于pymysql的参数化查询机制不能用来替换SQL中的标识符(比如表名、列名),它只适用于处理数据值(比如WHERE id = %s里的id值)。

当你用cursor.execute(sql, (table,))传递表名参数时,pymysql会把这个参数当作字符串值来处理,自动给它加上单引号,最终生成的SQL语句是:

SELECT * FROM 'table_1';

而MySQL里表名是不能用单引号包裹的(正确的做法是用反引号`包裹,或者如果表名是合法标识符的话可以不加),所以数据库会抛出语法错误,报错里的''table_1''其实是日志里对单引号的转义显示,实际就是'table_1'。

解决办法

要动态指定表名,你需要先严格校验表名的合法性(这一步非常关键,防止SQL注入攻击),然后用字符串拼接的方式生成SQL语句。

步骤1:校验表名

比如先定义一个允许访问的表名列表,只有在列表内的表名才允许查询:

ALLOWED_TABLES = {'table_1', 'table_2', 'user_info'}  # 替换成你实际的表名

步骤2:修改函数逻辑

在执行SQL前先校验表名,然后用字符串格式化拼接表名(用反引号包裹,避免表名包含特殊字符时出错):

import pymysql
import json

connection = pymysql.connect(
 host='localhost',
 user='u_u_u_u_u',
 password='passwd',
 db='test',
 charset='utf8mb4',
 cursorclass=pymysql.cursors.DictCursor
)

ALLOWED_TABLES = {'table_1'}  # 允许查询的表名单

def get_data(table):
    try:
        # 先校验表名合法性
        if table not in ALLOWED_TABLES:
            raise ValueError(f"Table {table} is not allowed to access")
        
        with connection.cursor() as cursor:
            # 用反引号包裹表名,处理特殊表名的情况
            sql = f"SELECT * FROM `{table}`;"
            cursor.execute(sql)
            result = cursor.fetchall()
            return json.dumps([dict(ix) for ix in result])
    except (TypeError, pymysql.err.ProgrammingError, ValueError) as error:
        print(error)
    finally:
        pass

get_data('table_1')
connection.close()
为什么不能用参数化处理表名?

参数化查询的设计初衷是为了防止SQL注入,同时自动处理数据值的类型转换(比如字符串加引号、日期格式化等)。但表名属于SQL的结构部分,不是数据值,所以驱动会把参数当作普通字符串值处理,加上引号后就破坏了SQL的语法结构。

永远不要直接拼接未校验的用户输入作为表名,否则会存在严重的SQL注入风险。必须通过白名单或者严格的正则校验来确保表名的合法性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:52:23