[Twisted-Python] Using adbapi w/Sybase stored procs

Allan Streib astreib at indiana.edu
Fri May 9 21:50:50 EDT 2003

Sybase stored procedures can return tabular results like a SQL query can.
This is unlike stored procedures in Oracle (not sure about other DBMSs)

I found (in 1.0.4) that I could not invoke such a procedure with the
runQuery method.  I developed the following subclasses that add a
"callProc" method which calls the procedure and fetches the results.

I could easily have added these methods to enterprise/adbapi.py but I
don't like to run locally modified distributions so I went the subclass
route for my needs.  Thought I'd share this so that someone could possbly
add it to the distribution.

I used this with the Sybase module for Python from Object Craft[1]

from twisted.enterprise import adbapi
from twisted.internet import defer, threads

class SybaseConnectionPool(adbapi.ConnectionPool):
    def __init__(self, dbapiName, *connargs, **connkw):
              (self, dbapiName) + connargs, connkw)

    def _callProc(self, args, kw):
        conn = self.connect()
        curs = conn.cursor()
            apply(curs.callproc, args, kw)
            result = curs.fetchall()
        return result

    def procedure(self, callback, errback, *args, **kw):
        threads.deferToThread(self._callProc, args, kw).addCallbacks(
            callback, errback)

class SybaseAugmentation(adbapi.Augmentation):
    def __init__(self, dbpool):
        adbapi.Augmentation.__init__(self, dbpool)

    def callProc(self, *args, **kw):
        d = defer.Deferred()
        apply(self.dbpool.procedure, (d.callback, d.errback)+args, kw)
        return d

The code to call a Sybase stored proc then looks like (patterned after the
example in the Twisted Book):

dbpool = SybaseConnectionPool("Sybase", "syb_server", "user", "pass")

class SybaseDatabase(SybaseAugmentation):
    def myProc(self, myArg):
	# A one-argument stored procedure...
        return self.callProc("dbname..my_proc", [myArg])

def gotResults(resultlist):
    """Callback for handling the result of the procedure"""
    print `resultlist`

db = SybaseDatabase(dbpool)
# These will *not* block. Hooray!

db.myProc("foo").addCallbacks(gotResults, db.operationError)

# Of course, nothing will happen until the reactor is started
from twisted.internet import reactor

 [1] http://www.object-craft.com.au/projects/sybase/

"If you understand what you're doing, you're not learning anything."
                                                -- Anonymous

More information about the Twisted-Python mailing list