-
Notifications
You must be signed in to change notification settings - Fork 361
Description
the test program below works without issue on all the 5.x cx_Oracle series, like 5.3, etc. When I run it on 6.0.2, I get random behavior, all seemingly related to the value "5748E+15". With outconverter set, I get just failures like:
AssertionError: set([Decimal('400000000'), Decimal('5749300000000000000'), Decimal('1521000000000000'), Decimal('100000000000')]) != set([Decimal('4E+8'), Decimal('5.748E+18'), Decimal('1E+11'), Decimal('1.521E+15')])
noting above, the exponent display is different, but that part is normal, the issue is the 5.748E value isn't coming back correctly - in my own test suites, sometimes it comes back as None also as though the outputtypehandler is getting skipped.
however more weirdly, if I use cursor.var(decimal.Decimal, ...) as cx_Oracle 6.0.x supports, then I get different errors each time, of the form:
decimal.InvalidOperation: Invalid literal for Decimal: '574A900000000000000'
decimal.InvalidOperation: Invalid literal for Decimal: '574?700000000000000'
decimal.InvalidOperation: Invalid literal for Decimal: '574:200000000000000'
decimal.InvalidOperation: Invalid literal for Decimal: '574:900000000000000'
if I remove the "5748E+15" value, then everything works without failing.
this is Oracle 11.2 express. I'm not sure if this is some weird known Oracle thing but if I use cx_Oracle 5.x, it goes away. This may well be within the realm of, "this won't work anymore on Oracle express on a laptop" but looking to see if you have some idea of what changed and what could cause this.
import cx_Oracle
import decimal
conn = cx_Oracle.connect(
user="scott",
password="tiger",
dsn=cx_Oracle.makedsn(
"172.17.0.3", 1521, sid="xe",
)
)
cursor = conn.cursor()
cursor.execute("""
CREATE TABLE t (
x NUMERIC(27, 4)
)
""")
try:
values = set([
decimal.Decimal('4E+8'),
decimal.Decimal("5748E+15"), # <--- this number is causing the problem
decimal.Decimal('1.521E+15'),
decimal.Decimal('00000000000000.1E+12')
])
cursor.executemany(
"INSERT INTO t (x) VALUES (:x)",
[{"x": value} for value in values]
)
def output_type_handler(cursor, name, defaultType,
size, precision, scale):
return cursor.var(
# using decimal.Decimal here on cx_Oracle 6.0.2 still breaks
cx_Oracle.STRING,
255,
outconverter=decimal.Decimal,
arraysize=cursor.arraysize)
cursor.outputtypehandler = output_type_handler
cursor.execute("SELECT x FROM t")
received = set([
row[0] for row in cursor.fetchall()
])
print "cx_Oracle version: %r" % cx_Oracle.__version__
print "Sent: %r Received: %r" % (values, received)
assert received == values, "%r != %r" % (received, values)
finally:
cursor.execute("DROP TABLE t")