[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"