使用pymysql executemany遇%d格式错误,求解决方案
解决PyMySQL executemany执行UPDATE语句的格式化异常问题
问题重现
使用PyMySQL的executemany批量更新数据时出现类型错误,简化代码如下:
cursor = self.connection.cursor() sql_query = f"UPDATE lançamento SET {column_name} = %s WHERE STR_TO_DATE(Data, '%d/%m/%Y') > %s AND Caixa = %s;" cursor.executemany(sql_query, [(str(value), str(current_date), self.back_end_insert_caixa_name) for value in values])
执行时抛出异常:
%d format: a real number is required, not str
尝试将%s改为%f并把str(value)转为float(value)后,又出现:
a real number is required not str
问题原因
SQL语句中STR_TO_DATE(Data, '%d/%m/%Y')里的%d、%m被PyMySQL的参数格式化机制误判为数值占位符,和我们用于传参的%s冲突,导致程序试图用传入的字符串参数匹配%d(要求整数),从而抛出类型错误。
解决方案
1. 转义SQL中的日期格式符
把STR_TO_DATE里的单个%替换为%%,避免被PyMySQL识别为参数占位符:
2. 正确传递参数类型
目标字段是float类型,直接传入float(value)即可,SQL中仍使用%s作为占位符(PyMySQL会自动完成类型映射,无需手动指定%f)。
修正后的代码:
cursor = self.connection.cursor() # 转义日期格式里的%为%% sql_query = f"UPDATE lançamento SET {column_name} = %s WHERE STR_TO_DATE(Data, '%%d/%%m/%%Y') > %s AND Caixa = %s;" # 参数直接传float类型,current_date如果是日期对象可直接传,无需转字符串 cursor.executemany(sql_query, [(float(value), current_date, self.back_end_insert_caixa_name) for value in values]) # 记得提交事务 self.connection.commit()
补充说明
PyMySQL中所有参数占位符统一使用%s,不管目标字段是数值、字符串还是日期,驱动会自动根据字段类型完成转换,手动指定%f、%d反而会引发格式解析错误。
内容的提问来源于stack exchange,提问作者DAVI AMÉRICO
相关产品推荐
相关产品推荐

