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

PyMySQL升级至v1.1.1后Cursor.execute参数格式化异常求助

PyMySQL 1.1.1参数格式化SQL错误问题及解决办法

问题背景

将环境迁移至新venv并把PyMySQL从v1.1.0升级到v1.1.1后,使用Cursor.execute格式化参数时出现SQL语法错误,尤其涉及numpy浮点类型和普通浮点类型的参数处理异常。

查询场景示例

client_id = float(2)
params = (client_id)
print(f"Parameters :\n\t{params}")
try:
    cursor.execute("SELECT * FROM clients WHERE id = %s", params)
except:
    print("EXCEPTION")
print(f"Query :\n\t{cursor._executed}")

执行输出:

Parameters :
    (2.0)
Query : 
    SELECT * FROM clients WHERE id = 2.0e0

此场景仅参数被转为科学计数法,不影响查询,但插入/更新场景会直接报错。

更新场景示例

client_id = float(2)
balance = np.float64(1000)
params = (client_id, balance)
print(f"Parameters :\n\t{params}")
try:
    cursor.execute("UPDATE client_balances SET balance = %s WHERE client_id = %s", params)
except:
    print("EXCEPTION")
print(f"Query :\n\t{cursor._executed}")

执行输出:

Parameters : 
    (2.0, np.float64(1000.0))
EXCEPTION
Query : 
    UPDATE client_balances SET balance = np.float64(1000)e0 WHERE client_id = 2.0e0

触发异常:

ProgrammingError - (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'e0, balance = np.float64(1000)e0, WHERE client_id = 2.0e0' at line 1")

临时解决方案(不推荐)

手动将参数转为字符串可正常执行,但存在类型转换开销和潜在精度问题:

client_id = float(2)
balance = np.float64(1000)
params = (client_id, balance)
print(f"Parameters :\n\t{params}")

refactored_params = []
for param in params:
    refactored_params.append(str(param))

try:
    cursor.execute("UPDATE client_balances SET balance = %s WHERE client_id = %s", refactored_params)
except:
    print("EXCEPTION")
print(f"Query :\n\t{cursor._executed}")

执行输出:

Parameters : 
    (2.0, np.float64(1000.0))
Query : 
    UPDATE client_balances SET balance = '1000' WHERE client_id = '2.0'

合理解决办法

1. 转换参数为原生Python类型

PyMySQL 1.1.1对非原生数值类型(如np.float64)的处理逻辑存在问题,需将其转换为原生Python数值类型:

client_id = int(float(2))  # 若id为整数类型,直接转int更合适
balance = float(np.float64(1000))
params = (client_id, balance)
cursor.execute("UPDATE client_balances SET balance = %s WHERE client_id = %s", params)

此方式让PyMySQL正确识别参数类型,生成合法的SQL语句。

2. 自定义通用参数转换函数

避免手动逐个转换,编写通用函数处理numpy数值类型:

import numpy as np

def normalize_params(params):
    converted = []
    for param in params:
        # 处理所有numpy数值类型
        if isinstance(param, np.number):
            converted.append(param.item())
        else:
            converted.append(param)
    return tuple(converted)

# 使用示例
client_id = float(2)
balance = np.float64(1000)
params = (client_id, balance)
cursor.execute("UPDATE client_balances SET balance = %s WHERE client_id = %s", normalize_params(params))

这个函数自动将numpy数值转为原生Python类型,适配所有参数场景,比手动转字符串高效且安全。

3. 验证版本差异与bug状态

检查PyMySQL 1.1.1的更新日志,确认是否为已知bug。如果是官方引入的问题,可临时降级至1.1.0,或等待官方修复版本发布。但降级需权衡版本兼容性,优先推荐前两种方案。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 10:24:56