[python-sybase] Decoding DataBuf objects?

Dave Cole djc at object-craft.com.au
Fri, 28 May 2004 10:38:16 +1000


Skip Montanaro wrote:

>I have a parameter dictionary filled in after a callproc() call:
>
>    >>> params
>    {'@e_year': <DataBufType object at 0x8138598>, '@e_month': <DataBufType object at 0x81384d0>, '@symbol': 'ZB', '@simulation_date': '20040527'}
>    >>> yr = params['@e_year']
>    >>> dir(yr)
>    ['count', 'datatype', 'format', 'maxlength', 'name', 'precision', 'scale', 'status', 'strip', 'usertype']
>    >>> yr.count
>    1
>    >>> yr.datatype
>    8
>    >>> yr.format
>    0
>    >>> yr.maxlength
>    4
>    >>> yr.name
>    '@e_year'
>    >>> yr.precision
>    0
>    >>> yr.scale
>    0
>    >>> yr.status
>    1024
>    >>> yr.strip
>    0
>    >>> yr.usertype
>    0
>    >>> yr[0]
>    2
>    >>> yr[1]
>    0
>    >>> yr[2]
>    IndexError: buffer index out of range
>    >>> len(yr)
>    1
>    >>> int(yr)
>    Traceback (most recent call last):
>      File "<stdin>", line 1, in ?
>    TypeError: int() argument must be a string or a number
>
>but can't tell how to actually get the real value out of it.  The actual
>value for the '@e_year' parameter is supposed to be 104.  I don't see it
>anywhere obvious.  The description of DataBuf objects in the docs doesn't
>seem to jive with what I have.
>
The databuf object is just a chunk of memory that is used by the Sybase 
libraries to exchange data with the server.  You cannot do anything 
interesting with the buffer except read Sybase native types out of the 
buffer to create a Python object, and write Python objects into the 
buffer as a Sybase native type.

What this means is that you need to do something like this:

    >>> params
    {'@e_year': <DataBufType object at 0x8138598>, '@e_month': <DataBufType object at 0x81384d0>, '@symbol': 'ZB', '@simulation_date': '20040527'}
    >>> yr = params['@e_year']
    >>> # yr is a memory buffer containing an array of Sybase native datatypes.
    >>> # We need to retrieve element zero of the array to get a Python object
    >>> # for the column value.
    >>> # The DataBufType is an array in order to support array binding using the
    >>> # Sybase API.
    >>> e_year = yr[0]

I hope that clears some things up.  It is a little non-obvious, but if you look at the fetch_rows() code in the following page you will see that the DataBufType is being used as an array to fetch column values.

	http://www.object-craft.com.au/projects/sybase/sybase/node21.html

- Dave

-- 
http://www.object-craft.com.au