[python-win32] Another ADO question

Jens B. Jorgensen jens.jorgensen@tallan.com
Wed, 25 Sep 2002 11:11:52 -0500


Paul,

Your code below is a little strange. First of all the Execute method of 
Connection returns a 2-tuple, not just a recordset. 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. On my system I observe:

 >>> rs, recs = cn.Execute('select sysdate from dual')
 >>> rs.Fields(0).Type == win32com.client.constants.adDBTimeStamp
1
 >>> rs.Fields(0).Value
<PyTime:9/25/2002 10:08:33 AM>
 >>> type(rs.Fields(0).Value)
<type 'time'>

I do see the other behavior:

 >>> rs, recs = cn.Execute('select 1 from dual')
 >>> rs.Fields(0).Value
u'1'

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:

 >>> rs, recs = sqls.Execute('select 1')
 >>> rs.Fields(0).Value
1
 >>> type(rs.Fields(0).Value)
<type 'int'>

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=KB;EN-US;Q327557&). 
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: 
http://www.pythonpros.com/cgi-bin/viewcvs.cgi/PyWin32/com/win32com/src/oleargs.cpp?rev=1.18&content-type=text/vnd.viewcvs-markup).

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.

Moore, Paul wrote:

>The ADO Recordset Field object seems to lose type information. No matter what type of value I select from the database, RS.Fields(x).Value always has unicode string type. Is this a limitation in ADO? Something not getting passed back correctly? I have used makepy...
>
>It's not the end of the world for numbers (I can always convert back from strings using int() or float() - although float() could lose precision, I guess) but it's a real pain for dates. Why isn't the field coming back as a VARIANT or the appropriate type? Can I make it do so?
>
>Sample code:
>
>    # Set up c as an ADO connection
>    rs = c.Execute("SELECT 1 FROM DUAL")
>    print `rs.Fields(0).Value`  # Gives u'1' rather than 1...
>
>Thanks,
>Paul.
>
>_______________________________________________
>Python-win32 mailing list
>Python-win32@python.org
>http://mail.python.org/mailman/listinfo/python-win32
>  
>

-- 
Jens B. Jorgensen
jens.jorgensen@tallan.com

"With a focused commitment to our clients and our people, we deliver value through customized technology solutions"