Oracle NUMBER casting to FLOAT

Discussion of open issues, suggestions and bugs regarding usage of ODBC Drivers
Post Reply
ron.dunn
Posts: 6
Joined: Wed 27 May 2015 11:30

Oracle NUMBER casting to FLOAT

Post by ron.dunn » Fri 06 Nov 2015 09:15

Columns which are declared as NUMBER are being returned by the driver as Python FLOAT values.

This seems incorrect, as they have no decimal places, and should probably be returned as an INTEGER.

Is there any way to force this behaviour at the driver level?

AlexP
Devart Team
Posts: 5530
Joined: Tue 10 Aug 2010 11:35

Re: Oracle NUMBER casting to FLOAT

Post by AlexP » Fri 06 Nov 2015 16:42

Hello,

Please provide the code you are using to define field type, since correct data is displayed when using the description method. For example, for the Dept table, whose Deptno field is declared as NUMBER(2, 0), the field is defined as <class 'int'>.

Code: Select all

>>> import pyodbc
>>> con = pyodbc.connect('DSN=ora')
>>> cur = con.cursor()
>>> cur.execute("select * from dept");
<pyodbc.Cursor object at 0x034855D0>
>>> cur.description
(('DEPTNO', <class 'int'>, None, 2, 2, 0, False), ('DNAME', <class 'str'>, None, 14, 14, 0, True), ('LOC', <class 'str'>, None, 13, 13, 0, True))
>>> 

ron.dunn
Posts: 6
Joined: Wed 27 May 2015 11:30

Re: Oracle NUMBER casting to FLOAT

Post by ron.dunn » Sat 07 Nov 2015 01:14

Here is a table definition taken from the CHINOOK sample database.

Code: Select all

CREATE TABLE InvoiceLine
(
    InvoiceLineId NUMBER NOT NULL,
    InvoiceId NUMBER NOT NULL,
    TrackId NUMBER NOT NULL,
    UnitPrice NUMBER(10,2) NOT NULL,
    Quantity NUMBER NOT NULL,
    CONSTRAINT PK_InvoiceLine PRIMARY KEY  (InvoiceLineId)
);
I'm running this database on AWS RDS Oracle.

Here is an equivalent script to yours, which shows that a column defined as NUMBER, not NUMBER(X,0), is being returned as FLOAT. An interesting point is that both precision and scale are being returned as 38 in this case.

Code: Select all

>>> import pyodbc
>>> connection_string = """
... 	Driver={Devart ODBC Driver for Oracle}; 
... 	Server=XXX; 
... 	SID=XXX; 
... 	Username=XXX;
... 	Password=XXX;
... 	UseUnicode=1; 
... 	Direct=1"""
... 
>>> con = pyodbc.connect (connection_string)
>>> cur = con.cursor()
>>> cur.execute ('select * from chinook.invoiceline')
<pyodbc.Cursor object at 0x0074F2C0>
>>> cur.description
(('INVOICELINEID', <class 'float'>, None, 38, 38, 38, False), ('INVOICEID', <class 'float'>, None, 38, 38, 38, False), ('TRACKID', <class 'float'>, None, 38, 38, 38, False), ('UNITPRICE', <class 'float'>, None, 10, 10, 2, False), ('QUANTITY', <class 'float'>, None, 38, 38, 38, False))
>>> 

AlexP
Devart Team
Posts: 5530
Joined: Tue 10 Aug 2010 11:35

Re: Oracle NUMBER casting to FLOAT

Post by AlexP » Mon 09 Nov 2015 10:01

According to the Oracle documentation, if precision and scalе are not set for a NUMBER field, then such field may contain values from 1 x 10^-130 to 9.99...9 x 10^125 up to 38 significant digits. Because of that we set precision and scalе to the value of 38.

Post Reply