From: Mike Bayer Date: Wed, 1 Aug 2018 18:12:49 +0000 (-0400) Subject: Bind Integers to int for cx_Oracle X-Git-Tag: rel_1_3_0b1~114^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=75d48e65eaac9e97283bb14fdec54a143d9997f1;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git Bind Integers to int for cx_Oracle For cx_Oracle, Integer datatypes will now be bound to "int", per advice from the cx_Oracle developers. Previously, using cx_Oracle.NUMBER caused a loss in precision within the cx_Oracle 6.x series. Change-Id: I4c6b2cca490aff5b98b7ceff3414715202881c89 Fixes: #4309 --- diff --git a/doc/build/changelog/unreleased_12/4309.rst b/doc/build/changelog/unreleased_12/4309.rst new file mode 100644 index 0000000000..c2e2221cb9 --- /dev/null +++ b/doc/build/changelog/unreleased_12/4309.rst @@ -0,0 +1,8 @@ +.. change:: + :tags: bug, oracle + :tickets: 4309 + + For cx_Oracle, Integer datatypes will now be bound to "int", per advice + from the cx_Oracle developers. Previously, using cx_Oracle.NUMBER caused a + loss in precision within the cx_Oracle 6.x series. + diff --git a/lib/sqlalchemy/dialects/oracle/cx_oracle.py b/lib/sqlalchemy/dialects/oracle/cx_oracle.py index 2225000f72..61fd0dbf4c 100644 --- a/lib/sqlalchemy/dialects/oracle/cx_oracle.py +++ b/lib/sqlalchemy/dialects/oracle/cx_oracle.py @@ -293,6 +293,10 @@ import time class _OracleInteger(sqltypes.Integer): + def get_dbapi_type(self, dbapi): + # see https://github.com/oracle/python-cx_Oracle/issues/208#issuecomment-409715955 + return int + def _cx_oracle_var(self, dialect, cursor): cx_Oracle = dialect.dbapi return cursor.var( diff --git a/lib/sqlalchemy/testing/suite/test_types.py b/lib/sqlalchemy/testing/suite/test_types.py index 4cdf14dc9e..04e0b3b23a 100644 --- a/lib/sqlalchemy/testing/suite/test_types.py +++ b/lib/sqlalchemy/testing/suite/test_types.py @@ -5,7 +5,8 @@ from ..assertions import eq_ from ..config import requirements from sqlalchemy import Integer, Unicode, UnicodeText, select, TIMESTAMP from sqlalchemy import Date, DateTime, Time, MetaData, String, \ - Text, Numeric, Float, literal, Boolean, cast, null, JSON, and_, type_coerce + Text, Numeric, Float, literal, Boolean, cast, null, JSON, and_, \ + type_coerce, BigInteger from ..schema import Table, Column from ... import testing import decimal @@ -337,6 +338,39 @@ class IntegerTest(_LiteralRoundTripFixture, fixtures.TestBase): def test_literal(self): self._literal_round_trip(Integer, [5], [5]) + def test_huge_int(self): + self._round_trip(BigInteger, 1376537018368127) + + @testing.provide_metadata + def _round_trip(self, datatype, data): + metadata = self.metadata + int_table = Table( + 'integer_table', metadata, + Column('id', Integer, primary_key=True, + test_needs_autoincrement=True), + Column('integer_data', datatype), + ) + + metadata.create_all(config.db) + + config.db.execute( + int_table.insert(), + {'integer_data': data} + ) + + row = config.db.execute( + select([ + int_table.c.integer_data, + ]) + ).first() + + eq_(row, (data, )) + + if util.py3k: + assert isinstance(row[0], int) + else: + assert isinstance(row[0], (long, int)) + class NumericTest(_LiteralRoundTripFixture, fixtures.TestBase): __backend__ = True diff --git a/test/dialect/oracle/test_types.py b/test/dialect/oracle/test_types.py index 2e52a97b7b..f8e8d41f88 100644 --- a/test/dialect/oracle/test_types.py +++ b/test/dialect/oracle/test_types.py @@ -968,12 +968,10 @@ class SetInputSizesTest(fixtures.TestBase): ) def test_smallint_setinputsizes(self): - self._test_setinputsizes( - SmallInteger, 25, testing.db.dialect.dbapi.NUMBER) + self._test_setinputsizes(SmallInteger, 25, int) def test_int_setinputsizes(self): - self._test_setinputsizes( - Integer, 25, testing.db.dialect.dbapi.NUMBER) + self._test_setinputsizes(Integer, 25, int) def test_numeric_setinputsizes(self): self._test_setinputsizes(