]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Bind Integers to int for cx_Oracle
authorMike Bayer <mike_mp@zzzcomputing.com>
Wed, 1 Aug 2018 18:12:49 +0000 (14:12 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 1 Aug 2018 23:21:13 +0000 (19:21 -0400)
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
doc/build/changelog/unreleased_12/4309.rst [new file with mode: 0644]
lib/sqlalchemy/dialects/oracle/cx_oracle.py
lib/sqlalchemy/testing/suite/test_types.py
test/dialect/oracle/test_types.py

diff --git a/doc/build/changelog/unreleased_12/4309.rst b/doc/build/changelog/unreleased_12/4309.rst
new file mode 100644 (file)
index 0000000..c2e2221
--- /dev/null
@@ -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.
+
index 2225000f724c350847336c534c796c71176bec7e..61fd0dbf4c46aeefe66f9f0a5304d1023d6971d4 100644 (file)
@@ -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(
index 4cdf14dc9e46bd964034eb6678955136c035fba9..04e0b3b23a55862d08b2aeed97743353bb060921 100644 (file)
@@ -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
index 2e52a97b7b68bb3a77e5419dd15af8ea3cf6cda7..f8e8d41f881bbb047722500d54877e22e7997896 100644 (file)
@@ -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(