[python-win32] Another ADO question

Moore, Paul Paul.Moore@atosorigin.com
Thu, 26 Sep 2002 10:07:41 +0100


From: Jens B. Jorgensen [mailto:jens.jorgensen@tallan.com]
> Your code below is a little strange. First of all the
> Execute method of Connection returns a 2-tuple, not just a
> recordset.

Yes, that was a bug in my code (fixed in the one I tested, but missed in =
the cut & paste). Sorry.

> But anyhow. I do notice that from Oracle integer
> types seem to come back as a string but this doesn't seem to
> be the case for me for dates.

That's good news. I didn't try (this time) to generate an example with =
dates - I'd had problems with dates previously and never fully =
understood them. When I got this problem with numbers, I mistakenly =
assumed the two were the same problem.

> However do not assume this behavior you're seeing is
> because of Python or ADO. For comparison's sake here's
> what I get talking to SQL Server 7:

That's good news. I didn't have a non-Oracle database to test against...

> I checked out the Provider-specific notes for my Oracle
> installation and it says that NUMBER types are returned
> as DBTYPE_VARNUMERIC. ADO maps this (if possible: the
> Oracle type supports greater precision than the underlying
> VARIANT type so if the number is bigger you get an
> exception) to VT_DECIMAL according the the KB article
> (http://support.microsoft.com/default.aspx?scid=3DKB;EN-US;Q32>7557&).
> Looking at the source for the Python win32
> extensions I can clearly see that VT_DECIMAL is
> simply converted to a string (see the function
> PyCom_PyObjectFromVariant in the source:

> So, this is the unfortunate state of things. A real source
> of the problem is that the VT_DECIMAL type is one which has
> no equivalent in Python with the requisite range. Probably
> the best solution is to create a new python class that
> would handle the values and support addition, subtraction,
> multiplication, etc. Minimally it should support conversion
> to float, int, and long integer types.

Agreed, this is unfortunate. And yes, I can see that we don't want to =
end up losing information by "guessing" a less-precise type. However, =
the DECIMAL->BSTR conversion is dependent on locale information, whereas =
the conversion in float() is not. Hence in a locale where the decimal =
separator is ",", float(rs(0).Value) may fail where the value is =
something like 1.2...

I don't see a useful way round this, short of some sort of DECIMAL type =
in Python. However, if the DECIMAL value is a whole number (you can =
check the bit pattern) would it be worth converting to a Python long? I =
don't know how problematic it would be having a VARIANT converted to =
different Python types depending on its *value* rather than just its =
*type* - but it is true that for most of my work I deal with integral =
values, and getting a Python integer (or long) would save 2 conversions, =
and some of my time (forgetting and fixing the problem...)

Nevertheless, thanks for the analysis of the problem. I hope my thoughts =
on the matter are of some value...

Paul.