我已經編寫了數據庫連接的上下文管理器。 我想重寫一個外部類(cx_oracle.Cursor中的'execute')的方法,在將查詢傳遞給數據庫之前刪除任何無關的綁定變量(否則它們會導致DatabaseError)。他們爲什麼會在那裏開始的問題是正交的。覆蓋外部庫中的python實例方法
下面的作品,但我不知道我是否正在使用_ 的getAttribute _正確位置(有沒有真正有一個藉口之前使用它)。
我也是「全耳朵」......呃眼睛......如果有人有更好的建議,就如何從這個外部圖書館中超越這種方法。
謝謝。我使用python 2.7
import cx_Oracle
from contextlib import contextmanager
class Cursor(cx_Oracle.Cursor):
"""A wrapper for cx_Oracle cursors that will drop extraneous bind variables passed to in"""
def __init__(self, curs):
self.curs = curs
def execute(self, sql, *args, **kwargs):
params = {}
print("in execute, args[0] = [%s]" % str(args[0]))
if len(args) == 1 and isinstance(args[0], dict):
for bv in args[0].keys():
if ':%s' % bv in sql:
params[bv] = args[0][bv]
print('params = %s' % str(params))
else:
return self.curs.execute(sql, *args, **kwargs)
return self.curs.execute(sql, params)
def __getattribute__(self, name):
if name == 'execute':
return object.__getattribute__(self, name)
elif name == 'curs':
return object.__getattribute__(self, 'curs')
else:
curs = object.__getattribute__(self, 'curs')
return cx_Oracle.Cursor.__getattribute__(curs, name)
@contextmanager
def db_conn():
pool = cx_Oracle.SessionPool("user", "pwd", "database", min=2, max=10, increment=1, threaded=True)
conn = pool.acquire()
try:
yield Cursor(conn.cursor())
except:
conn.rollback()
raise
else:
conn.commit()
finally:
pool.release(conn)
if __name__ == '__main__':
with db_conn() as curs:
curs.execute('select * from dual where 1 = :a', {'a':1, 'b':2})
print(curs.fetchall())
謝謝!這看起來完全像我想要的(我需要更熟悉特殊的方法)。我開始繼承cx_Oracle.Cursor的唯一原因是自動獲得其他方法。這給了我。 – Gerrat 2011-04-19 20:58:22
@Gerrat:不客氣。這裏有很多信息:http://docs.python.org/reference/datamodel.html – 2011-04-19 22:07:33