Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.Sign up
regression in numeric precision behavior in 6.0 #68
Using cx_Oracle.NUMERIC with setinputsizes is now causing truncation under cx_Oracle 6.0.
output under 5.2:
output under 6.0:
if I remove the call to setinputsizes(), it works.
added a commit
Aug 18, 2017
So if you call cursor.setinputsizes() to specify the use of cx_Oracle.NUMBER, the code silently converts decimal to float, which is what resulted in the truncation. I have added the type check back in again so that this will fail and the default bind will take place instead. Generally, unless you are binding null and need to specify the type, you're better off letting cx_Oracle determine the type from the input data. Note as well, that you could also use cursor.setinputsizes(decimal.Decimal) which would also have eliminated the issue.
still trying, after many years, to get a handle on exactly which types I should be calling setinputsizes(), and which I should not, in cx_Oracle. Right now the SQLAlchemy does it for all types except STRING. in https://bitbucket.org/zzzeek/sqlalchemy/issues/4035#comment-38706596, you seemed to be saying that if I dont use setinputsizes() for STRING, I'm going to get inconsistent results in Python 2 vs. Python 3, and I haven't even gotten to work on that as just setting STRING caused lots of test failures right off.
Then, using decimal.Decimal in setinputsizes(), will that work in cx_Oracle 5 also ?
Right now it seems to be that I should not be calling setinputsizes() in any cases except when a LOB type is being passed but I wonder if I was using it for Numeric due to behaviors in older versions of cx_Oracle like 5.x or even 4.x? Not really sure.
I understand your pain. If I could go back in my time machine, I would have ensured that both string and unicode in Python 2.x bound to VARCHAR2 in the database. Unfortunately, we're stuck with the situation where if you bind a string you bind to VARCHAR2 but if you bind a unicode value (Python 2.x) you bind to NVARCHAR2.
In general, I recommend not using setinputsizes() unless the type that cx_Oracle would figure out by itself doesn't match the type you require in the database (such as when binding a null value). Since you're writing generic code for SQLAlchemy, however, that recommendation doesn't work as well for you. I would recommend using the Python types (str, int, float, decimal.Decimal, datetime.datetime) when calling setinputsizes() as the generic DB API types cover too much ground and the defaults may not work for you, especially for things like numbers (cx_Oracle.NUMBER effectively means floating point numbers).
Yes, that works in cx_Oracle 5, too.
The method executemany() will use the first non-null value to determine the type for each bind variable.
Hope that answers your questions! Feel free to ask further if you need further input.