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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 20:02:43