[python-sybase] NumericType not hashable?

Harri Pasanen harri.pasanen at trema.com
Mon, 13 May 2002 15:18:23 +0200


On Monday 06 May 2002 09:23, Dave Cole wrote:
> > By the looks of it, NumericType is not python hash table friendly.
>
> It should be...  Can you tell us how you built the module and which
> platform you are using?
>

This was on Linux, Python 2.2, Sybase module 0.34, built from source and 
installed with "python setup.py install".

But looking at my own testcase, I can see I was in a rush, the testcase is 
incomplete.   So I guess this was a false alarm, sorry for the noice.

-Harri

> This is what happens when I try using the hash functionality:
> >>> import Sybase
> >>> n = Sybase.numeric(2)
> >>> type(n)
>
> <type 'NumericType'>
>
> >>> d = {n: 'two' }
> >>> d[2]
>
> 'two'
>
> >>> m = Sybase.numeric(3L)
> >>> d[m] = 'three'
> >>> d[3]
>
> 'three'
>
> >>> o = Sybase.numeric('4')
> >>> d[o] = 'four'
> >>> d[4]
>
> 'four'
>
> With my new 0.35pre1 callback error handling I now have problems with
> longs...
>
> >>> m = Sybase.numeric(1231312313123133L)
> >>> m
>
> 1231312313123133
>
> >>> hash(m)
>
> Traceback (most recent call last):
>   File "<stdin>", line 1, in ?
>   File "Sybase.py", line 133, in _cslib_cb
>     raise Error(_fmt_client(msg))
> Sybase.Error: Layer: 2, Origin: 4
> cs_convert: cslib user api layer: common library error: The
> conversion/operation resulted in overflow.
>
> The numeric hash calculation tries to convert to an integer first in
> order to work out an integer compatible hash.  So it looks like I am
> going to have to create a fully internal CS_CONTEXT for doing things
> which I know might fail - such as attempts to convert NumericType to
> integer before doing a conversion to string then to long in order to
> calculate the hash.
>
> > That means that something like:
> >
> > c.execute('select id, limit_id, name from Sublimit_cvt')
> > rows = c.fetchall()
> > for row in rows:
> >     id, limit_id, name = row
> >
> > c.execute('select id from MyTable')
> > rows = c.fetchall()
> > for row in rows:
> >   id = row[0]
> >   print map[id]
> >
> >
> > will fail if id is of type AutomaticID in Sybase.
> >
> > I'm not sure if this is required by DB API, but I think it violates
> > the principle of least surprise.
>
> can you try doing something like this:
>
> c.execute('select id, limit_id, name from Sublimit_cvt')
> rows = c.fetchall()
> for row in rows:
>     id, limit_id, name = row
>     print id, type(id), hash(id)
>
> > My workaround was to force a conversion to string, so my code now
> > reads map[str(id)]. But maybe NumericType should be modified to act
> > as any number when used as a hash key?  Any opinions?
>
> It Already Does (TM) so I suspect there is something else going on,
> maybe related to the compilation.
>
> - Dave