pymysql.cursor.executemany()执行报错,是否为框架Bug?
问题分析与解决方案
这是pymysql在处理executemany()结合命名占位符的ON DUPLICATE KEY UPDATE语句时的已知实现限制,并非你的代码逻辑错误。
原因
execute()单条执行时,命名占位符%(xxx)s能被正确绑定到单个参数字典;但executemany()批量执行时,pymysql无法正确关联ON DUPLICATE KEY UPDATE子句中的命名参数与批量数据的对应关系,导致生成的SQL语法错误。
解决方法(两种可选)
方法1:改用VALUES(col)引用插入值(推荐)
修改SQL语句,让UPDATE部分直接引用当前行插入的字段值,无需重复绑定参数:
sql=""" insert into test (route, direction, timestamp, stations) values ( %(route)s, %(direction)s, %(timestamp)s, %(stations)s ) on duplicate key update timestamp=VALUES(timestamp), stations=VALUES(stations) """ cur.executemany(sql, [ret1, ret2]) conn.commit()
这种方式利用MySQL原生语法,让VALUES(timestamp)自动对应当前行插入的timestamp值,避免了pymysql的参数绑定冲突。
方法2:改用位置占位符%s
如果坚持使用参数绑定,可将命名占位符改为位置占位符,并在参数列表中重复传入UPDATE所需的字段值:
sql=""" insert into test values ( %s, %s, %s, %s ) on duplicate key update timestamp=%s , stations=%s """ # 每个参数元组需包含插入+更新的所有字段值 params = [ ('N2', 0, now, j, now, j), ('N1', 0, now, j, now, j) ] cur.executemany(sql, params) conn.commit()
版本说明
pymysql 1.x版本中存在此批量命名参数的兼容性问题,若需保持命名参数写法,优先选择方法1。
内容的提问来源于stack exchange,提问作者DDDreamer
相关产品推荐
相关产品推荐

