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

使用LoggingCursor时自定义cursor_class不兼容dictionary属性问题

解决mysql-connector-python自定义C扩展游标同时返回字典格式结果的问题

问题背景

使用mysql-connector-python==9.0.0时,默认通过以下方式可让游标以字典形式返回结果:

cursor = db.cursor(dictionary=True)

但当自定义继承CMySQLCursor的LoggingCursor类,并通过cursor_class指定时,dictionary=True参数会被忽略,结果仍以元组返回:

cursor = db.cursor(cursor_class=LoggingCursor, dictionary=True)

自定义LoggingCursor代码如下:

class LoggingCursor(CMySQLCursor):
    def __init__(self, *args, **kwargs):
        super(LoggingCursor, self).__init__(*args, **kwargs)
        self.executed_statements: list[str] = []

    def execute(self, operation, params=(), multi=False):
        result = super(LoggingCursor, self).execute(operation, params, multi)
        self.executed_statements.append(self.statement)
        return result

    def executemany(self, operation, seq_params):
        result = super(LoggingCursor, self).executemany(operation, seq_params)
        for _ in seq_params:
            self.executed_statements.append(self.statement)
        return result

    @property
    def all_executed_statements(self):
        return self.executed_statements

另外必须使用C扩展游标,使用默认mysql.connector.cursor.MySQLCursor会报错:

mysql.connector.errors.ProgrammingError: Cursor class needs to be a subclass of cursor_cext.CMySQLCursor 

解决方案

问题核心是:dictionary=True本质是让连接器使用CMySQLCursorDict(字典格式的C扩展游标),而你的自定义游标继承的是基础的CMySQLCursor(元组格式),因此指定cursor_class后,dictionary参数无法生效。

只需修改自定义游标继承的父类为CMySQLCursorDict,即可同时保留日志功能和字典返回格式:

from mysql.connector.cursor_cext import CMySQLCursorDict

class LoggingCursor(CMySQLCursorDict):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.executed_statements: list[str] = []

    def execute(self, operation, params=(), multi=False):
        result = super().execute(operation, params, multi)
        self.executed_statements.append(self.statement)
        return result

    def executemany(self, operation, seq_params):
        result = super().executemany(operation, seq_params)
        for _ in seq_params:
            self.executed_statements.append(self.statement)
        return result

    @property
    def all_executed_statements(self):
        return self.executed_statements

之后初始化游标时,直接指定cursor_class即可,无需再传dictionary=True(传参也不会冲突):

cursor = db.cursor(cursor_class=LoggingCursor)

这样自定义游标既保留了SQL语句日志记录功能,又能以字典形式返回查询结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 11:22:39