问题描述
有一个cx-Oracle模块。我想装饰Cursor类的执行方法,以便它记录正在执行的请求:
import logging
class _QueryLogger:
def __init__(self, execute_func):
self._func = execute_func
self._logger = logging.getLogger()
def __call__(self, query: str):
self._logger.log(level=logging.DEBUG, msg=query)
return self._func(query)
然后,通过上下文管理器,返回带有修饰方法的游标对象execute:
import cx_Oracle
from credentials import credentials
from deco import _QueryLogger
class DbOracle:
@contextmanager
def _get_cursor(self):
with cx_Oracle.Connection(**credentials) as conn:
cursor = conn.cursor()
cursor.execute = _QueryLogger(cursor.execute) # Проблема здесь
yield cursor
def execute(self, query):
with self._get_cursor() as cursor:
cursor.execute(query)
使用时:
oracle = DbOracle()
oracle.execute("select * from v$version")
出现异常:
AttributeError: 'cx_Oracle.Cursor' object attribute 'execute' is read-only
问题
如何绕过?我想将日志记录添加到游标对象本身,通过它执行查询。
为什么
DbOracle 类有几种方法用于执行各种 SQL 查询。我想将日志记录附加到游标对象,以便在这些方法中的每一个中,请求在执行之前都不会被记录(读取,以避免代码重复)。
结果证明这是一个理性的决定。