First draft or oracleconn.py
[email protected] Sun, 5 Jun 2005 00:06:24 +0100
| Newsgroups | gmane.comp.web.skunkweb |
|---|---|
| Message-ID | <[email protected]> |
I've attached the first draft of an Oracle driver for PyDO 2. It doesn't yet implement listTables and describeTable, but otherwise it appears to be basically functional (assuming I haven't since introduced any bugs in the process of tidying it up and commenting it, which I haven't been able to test yet!). Hamish Lawson ----------------------------------------------------------------- University of St Andrews Webmail: http://webmail.st-andrews.ac.uk
oracleconn.py
(text/plain, 3 KB)
from pydo.dbi import DBIBase, ConnectionPool
from pydo.exceptions import PyDOError
from pydo.operators import BindingConverter
from pydo.dbtypes import DATE, TIMESTAMP, BINARY, INTERVAL
from pydo.log import debug
from pydo.field import Field
from itertools import izip
import cx_Oracle
class OracleResultSet(object):
"""A resultset that for each row reads the content of any LOBs before
the LOB locators get invalidated by a subsequent fetch. To accommodate
this, field access is mediated via an appropriate handler."""
def __init__(self, resultset, description):
self.resultset = iter(resultset)
self.handlers = [self.get_handler(x[1]) for x in description]
@staticmethod
def get_handler(fieldtype):
if fieldtype in (cx_Oracle.CLOB, cx_Oracle.BLOB, cx_Oracle.LOB):
return lambda item: item.read()
else:
return lambda item: item
def __iter__(self):
return self
def next(self):
return [handler(item) for (item, handler)
in izip(self.resultset.next(), self.handlers)]
class OracleDBI(DBIBase):
paramstyle = 'named'
autocommit = None
def __init__(self, connectArgs, pool=None, verbose=False):
if pool and not hasattr(pool, 'connect'):
pool = ConnectionPool()
super(OracleDBI, self).__init__(connectArgs, cx_Oracle.connect, pool, verbose)
def execute(self, sql, values=(), qualified=False):
"""Executes the statement with the values and does conversion
of the return result as necessary.
result is list of dictionaries, or number of rows affected"""
if self.verbose:
debug("SQL: %s", sql)
debug("bind variables: %s", values)
c = self.conn.cursor()
if values:
c.execute(sql, values)
else:
c.execute(sql)
if c.description is None:
resultset = None
else:
resultset = OracleResultSet(c, c.description)
if not resultset:
return c.rowcount
res = self._convertResultSet(c.description, resultset, qualified)
c.close()
return res
def getSequence(self, name):
cur=self.conn.cursor()
sql="select %s.nextval from dual" % name
if self.verbose:
debug("SQL: %s", (sql,))
cur.execute(sql)
res=cur.fetchone()
if not res:
raise PyDOError, "could not get value for sequence %s!" % name
return res[0]
def listTables(self, schema=None):
"""list the tables in the database schema"""
raise NotImplementedError
def describeTable(self, table, schema=None):
"""for the given table, returns a 2-tuple: a dict of Field objects
keyed by name, and list of multi-column unique constraints (sets of Fields)).
The Field instances should contain information about whether they are unique
or sequenced.
"""
raise NotImplementedError