[python-sybase] Re: This routine cannot be called because another
command structure has results pending
Greg Ward
gward-pysybase at python.net
Thu Jul 6 02:47:25 EST 2006
On 22 June 2006, I said:
> Back in May 2002, Ralph Heinkel reported a mysterious error, "This
> routine cannot be called because another command structure has results
> pending". Here's his post:
>
> http://www.object-craft.com.au/pipermail/python-sybase/2002-May/000034.html
>
> He posted a test program that reproduces the problem, and it still
> reproduces perfectly for me. It appears that any error on a connection
> renders that connection unusable, or at least un-commit()able and
> un-rollback()able. I'm connecting to Sybase ASE 11.0.3.3 (using
> libct.so and libcs.so supplied with the Sybase engine) and python-sybase
> 0.37.
I've done a bit more digging into this problem and discovered a crude
workaround. All I have to do is add one line of code after my failed
query but before closing the cursor:
cur = db.cursor()
try:
# produce an error - THE TABLE 'DUMMY' DOES NOT EXIST
cur.execute('select * from dummy')
print "WTF?!? select should have failed!"
except Sybase.Error, err:
print "select failed as expected: %s" % err
cur._fetcher._close() <--- CRUDE WORKAROUND
cur.close()
db.commit()
That suggests to me that the bug lies in python-sybase rather than in my
code or in ctlib. I think the bug is that Sybase.py assumes that
self._fetcher = None
is sufficient to close the fetcher object and release all of its
resources, most importantly by calling ct_cancel() on the underlying
ctlib command structure. Here's a narrow-minded patch that fixes the
particular problem I'm seeing:
--- Sybase.py.orig 2005-04-06 18:46:43.000000000 -0400
+++ Sybase.py.hacked 2006-07-05 12:41:55.000000000 -0400
@@ -735,10 +735,12 @@
def close(self):
'''DB-API Cursor.close()
'''
if self._closed:
raise ProgrammingError('cursor is closed')
+ if self._fetcher:
+ self._fetcher._close()
self._fetcher = None
self._closed = 1
def execute(self, sql, params = {}):
'''DB-API Cursor.execute()
However, I suspect a more appropriate fix would be to factor out a
_close_fetcher() method of Cursor:
def _close_fetcher(self):
if self._fetcher:
self._fetcher._close()
self._fetcher = None
and replace every occurence of "self._fetcher = None" with
"self._close_fetcher()".
Does this sound close? If so, I'll happily provide a patch.
Greg
More information about the Python-sybase
mailing list