[Zope-DB] Patches to SybaseDA v2.0b2

Doug Morse morse at pobox.com
Thu Apr 20 18:40:58 EDT 2006


In migrating from Sybase 11.0.3 (old, free version for Linux) to Sybase 15
(free Linux Express version), I've had quite a number of troubles getting
SybaseDAv2b2 to work (under Zope 2.5.1).  That said, the problems probably
had more to do with changing from Python 2.1.3 (Redhat 7.2) to Python 2.3.4
(RHEL 4.3).

In particular, the newer Python more stringently checks the parameters
passed to the PyArg_ParseTupleAndKeywords() function.  sys_occ.c in
SybaseDAv2b2 has a very minor (but fatal) error in this regard that, because
of the new checks, cause the somewhat esoteric error message:

  RuntimeError: more keyword list entries than argument specifiers

I've included below patches to two files, db.py and src/sys_occ.c, that fix
this error.

The patches also provide a workaround for the first error I encountered that
stumped me for a bit:

  ct_command(): user api layer: external error: This routine cannot be
  called while results are pending for a command that has been sent to the

This error occurred anytime I tried to access the database (i.e., I could
connect just fine, but could not run any queries).  The solution simply adds
a call to "cm.ct_cancel(sy_occ.CS_CANCEL_ALL)" early on in the "query"
method to clear the pending results and hence stop this error from

IMPORTANT CAVEAT: This call to cm.ct_cancel() may not be appropriate as a
general solution, as it's possible that the workaround will mess up a
multistep query, such as an INSERT, UPDATE, or DELETE transaction.  The
proper fix would require finding out why SybaseDAv2b2 has some sort of
results pending even at the first call of the "query" method and then fixing
this by either retrieving the remaining results or cancelling the offending

I presently only require read-only access for rather simply queries
from Zope to Sybase 15, so this workaround is fine for me for now.  If
anyone investigates this further and has a better solution, I'd appreciate

I hope this is helpful to some soul or souls out there. :)  Sybase ASE 15 is
a great product, free for Linux for up to 5gb DBs and 2gb RAM, and worthy of
partnering with Zope for the presentation side of things.


P.S. the patch also corrects the erroneous duplication of the
CS_SUCCEED command entry (noted long ago on this list) and puts a try/catch
block around a call to "apply(converters[t], v)", also suggested by some
poster either on this or another list.

PATCH #1: db.py

*** db.py	2000-02-02 14:01:34.000000000 -0600
--- /opt/zope/lib/python/Products/SybaseDAv2/db.py	2006-04-19 19:00:13.000000000 -0500
*** 178,184 ****
-               CS_SUCCEED=sy_occ.CS_SUCCEED,
--- 178,183 ----
*** 196,201 ****
--- 195,201 ----
          for query in queries:
+             cm.ct_cancel(sy_occ.CS_CANCEL_ALL)
              if cm.ct_command(CS_LANG_CMD, query) != CS_SUCCEED: self._error()
              if cm.ct_send() != CS_SUCCEED: self._error()
*** 280,287 ****
!                                         if type(v) is TupleType:
!                                             v=apply(converters[t], v)
--- 280,295 ----
! #                                         if type(v) is TupleType:
! #                                             v=apply(converters[t], v)
!                                         try:
!                                             if type(v) is TupleType:
!                                                 v=apply(converters[t], v)
!                                         except:
!                                             cm.ct_cancel(sy_occ.CS_CANCEL_ALL)
!                                             raise Error("Results field conversion error: converter=%s, v=%s" % \
!                                                         (str(converters[t]), str(v)))

PATCH #2: src/sy_occ.c

*** src/sy_occ.c	2000-02-02 14:01:34.000000000 -0600
--- /opt/zope/lib/python/Products/SybaseDAv2/src/sy_occ.c	2006-04-20 00:17:23.000000000 -0500
*** 382,388 ****
    static char *kwargs[] = {"name", "datatype", "format", "maxlength",
  			   "scale", "precision", "status", "count", 
! 			   "usertype", "locale"};
    if (!PyArg_ParseTupleAndKeywords(
  	  args, kw, "|s#iiiiiiiiO!", kwargs,
--- 382,388 ----
    static char *kwargs[] = {"name", "datatype", "format", "maxlength",
  			   "scale", "precision", "status", "count", 
! 			   "usertype", "loc", NULL};
    if (!PyArg_ParseTupleAndKeywords(
  	  args, kw, "|s#iiiiiiiiO!", kwargs,

More information about the Zope-DB mailing list