[DB-SIG] Sybase module 0.33 released
Dave Cole
djc@object-craft.com.au
10 Mar 2002 16:58:25 +1100
What is it:
The Sybase module provides a Python interface to the Sybase relational
database system. It supports all of the Python Database API, version
2.0 with extensions.
Note:
Since the 0.32 release I have come to the realisation that the Sybase
dynamic SQL functionality is not nearly general enough to use for
correct DB-API functionality. I have thrown up my hands and gone back
to the drawing board with the high level Sybase.py module.
There were four pre-releases of the module. The following is a
summary of what has changed since 0.32:
1) Bulkcopy support has been temporarily removed from Sybase.py. The
low level support is still present in the sybasect extension module.
2) Cursors are no longer using dynamic SQL so there will no
longer be an extra result set which reported the status of the
temporary stored procedure. This should remove some of the
confusion behaviour of cursors.
There should be fewer restrictions on the use of cursors.
3) The paramstyle is now 'named'. This means that you can now do
this:
c.execute("select * from titles where title like @arg",
{'@arg': 'The %'})
4) You can send arguments to Cursor.callproc() the old way:
c.callproc('sp_help', ['titles'])
or the new way:
c.callproc('sp_help', {'@objname': 'titles'})
5) Some internal cursor state constants were privatised (via leading
'_'). Sadly no money was raised in the process and the conditions
of the privatisation contract are commercial-in-confidence.
6) You can now compile the extension module without bulkcopy support
by doing this:
python setup.py build_ext -U WANT_BULKCOPY
python setup.py install
7) The default build does not do threading any more so if you want
threading enabled you will have to do this:
python setup.py build_ext -D WANT_THREADS
python setup.py install
8) There is some initial work to support FreeTDS. One of the problems
with FreeTDS is that it does not support inline error handling.
The callback error handling works well if you do not compile for
threads support, but causes problems when compiled for threading.
The problem occurs when the extension module releases the global
interpreter lock when calling the Sybase CT library. A Python
callback causes the interpreter to be reentered by the callback
which leads to bad things when the following warning from the
Python include file ceval.h is violated:
WARNING: NEVER NEST CALLS TO Py_BEGIN_ALLOW_THREADS AND
Py_END_ALLOW_THREADS!!!
At the moment the module will compile for FreeTDS (at least it does
on my machine) and some things do work. All you have to do is
compile like this:
python setup.py build_ext -D HAVE_FREETDS -U WANT_BULKCOPY
python setup.py install
There is no error handling and reporting for FreeTDS yet.
9) There is now some basic locale support in the sybasect extension
module. I do not have a need for this so am really depending upon
someone to try it and report problems:
>>> from sybasect import *
>>> status, ctx = cs_ctx_alloc()
>>> status, loc = ctx.cs_loc_alloc()
>>> loc.cs_locale(CS_GET, CS_SYB_LANG)
(1, 'us_english')
>>> loc.cs_dt_info(CS_GET, CS_DT_CONVFMT)
(1, 3)
>>> loc.cs_dt_info(CS_GET, CS_MONTH, 1)
(1, 'February')
>>> loc.cs_dt_info(CS_GET, CS_DATEORDER)
(1, 'dmy')
In theory you could do something like this:
>>> import Sybase
>>> from Sybase import _ctx, CS_SUCCEED, CS_SET, CS_SYB_LANG, CS_LOC_PROP
>>>
>>> status, locale = _ctx.cs_loc_alloc()
>>> if status != CS_SUCCEED:
... raise 'cs_loc_alloc'
...
>>> if locale.cs_locale(CS_SET, CS_SYB_LANG, 'french') != CS_SUCCEED:
... raise 'cs_locale CS_SYB_LANG'
...
>>> db = Sybase.connect('SYBASE', 'sa', '', delay_connect = 1)
>>> db.set_property(CS_LOC_PROP, locale)
>>> db.connect()
10) There is some extra debugging detail for CS_DATAFMT which means you
now get messages like this:
>>> import Sybase
>>> db = Sybase.connect('SYBASE', 'sa', '', 'pubs2')
>>> db._conn.debug = 1
>>> c = db.cursor()
ct_cmd_alloc(conn0, &cmd) -> CS_SUCCEED, cmd1
>>> c.callproc('sp_help', {'@objname': 'titles'})
ct_command(cmd1, CS_RPC_CMD, "sp_help", CS_NULLTERM, CS_UNUSED) -> CS_SUCCEED
ct_param(cmd1, &databuf0->fmt=[name:"@objname" type:CS_CHAR_TYPE status:CS_INPUTVALUE format:CS_FMT_NULLTERM count:1 maxlength:7], databuf0->buff, 6, 0) -> CS_SUCCEED
ct_send(cmd1) -> CS_SUCCEED
ct_results(cmd1, &result) -> CS_SUCCEED, CS_ROW_RESULT
ct_res_info(cmd1, CS_NUMDATA, &value, CS_UNUSED, NULL) -> CS_SUCCEED, 3
ct_describe(cmd1, 1, &fmt) -> CS_SUCCEED, datafmt0=[name:"Name" type:CS_CHAR_TYPE status:CS_UPDATABLE format:CS_FMT_UNUSED count:0 maxlength:30]
ct_bind(cmd1, 1, &datafmt0->fmt=[name:"Name" type:CS_CHAR_TYPE status:CS_UPDATABLE format:CS_FMT_UNUSED count:1 maxlength:30], databuf1->buff, databuf1->copied, databuf1->indicator) -> CS_SUCCEED, databuf1
ct_describe(cmd1, 2, &fmt) -> CS_SUCCEED, datafmt1=[name:"Owner" type:CS_CHAR_TYPE status:48 format:CS_FMT_UNUSED count:0 maxlength:30]
ct_bind(cmd1, 2, &datafmt1->fmt=[name:"Owner" type:CS_CHAR_TYPE status:48 format:CS_FMT_UNUSED count:1 maxlength:30], databuf2->buff, databuf2->copied, databuf2->indicator) -> CS_SUCCEED, databuf2
ct_describe(cmd1, 3, &fmt) -> CS_SUCCEED, datafmt2=[name:"Type" type:CS_CHAR_TYPE status:48 format:CS_FMT_UNUSED count:0 maxlength:22]
ct_bind(cmd1, 3, &datafmt2->fmt=[name:"Type" type:CS_CHAR_TYPE status:48 format:CS_FMT_UNUSED count:1 maxlength:22], databuf3->buff, databuf3->copied, databuf3->indicator) -> CS_SUCCEED, databuf3
11) The was a minor change to setup.py for Linux. No longer looks for
both libsybtcl and libtcl. Now just looks for libinsck.
12) The tar file now unpacks to a directory called sybase-<release>.
The module is available here:
http://www.object-craft.com.au/projects/sybase/sybase-0.33.tar.gz
The module home page is here:
http://www.object-craft.com.au/projects/sybase/
- Dave
--
http://www.object-craft.com.au