使用Peewee execute_sql执行多语句事务SQL报错求助
问题分析与解决方案
核心原因
Peewee的execute_sql方法默认不启用多语句执行(即不允许单次执行多个分号分隔的SQL语句),而你的SQL包含START TRANSACTION+多段UPDATE,触发了驱动的安全限制。MySQL Connector需要显式指定multi=True才能执行多语句,但Peewee默认未传递该参数,这就是报错的原因。
解决方案
方案1:使用Peewee内置事务管理(推荐)
放弃手动编写START TRANSACTION,改用Peewee原生的atomic()上下文管理器处理事务,既符合框架规范,又避免多语句问题:
class MySQLClient(DBClient): def batch_update(self, update_queries): self.reconnect_if_needed() try: with self.db.atomic(): # 自动处理START TRANSACTION、COMMIT/ROLLBACK for qry in update_queries: self.db.execute_sql(qry) logger.info("Batch updates executed successfully") except Exception as e: logger.error(f"Error executing batch updates: {e}") # atomic上下文会自动回滚,无需手动调用rollback
方案2:强制启用多语句执行(需注意安全风险)
如果必须保留原SQL的写法,需要直接操作底层MySQL Connector的cursor,显式传入multi=True参数:
class MySQLClient(DBClient): def op(self, qry): self.reconnect_if_needed() cursor = None results = [] try: cursor = self.db.cursor() # 获取底层驱动cursor # 启用多语句执行 for result in cursor.execute(qry, multi=True): if result.with_rows: # 仅处理有返回结果的语句 results.extend(result.fetchall()) self.db.commit() logger.info(f"Query executed successfully: {qry}") except Exception as e: logger.error(f"Error executing query: {e}") self.db.rollback() finally: if cursor: cursor.close() return results
注意:启用
multi=True会增加SQL注入风险,确保执行的SQL是完全可信的,禁止直接拼接用户可控的输入内容。
内容的提问来源于stack exchange,提问作者Mohammed Fayis P
相关产品推荐
相关产品推荐

