]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- Ensured every numeric, float, int code, scalar + array,
authorMike Bayer <mike_mp@zzzcomputing.com>
Thu, 18 Nov 2010 23:10:03 +0000 (18:10 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Thu, 18 Nov 2010 23:10:03 +0000 (18:10 -0500)
are recognized by psycopg2 and pg8000's "numeric"
base type. [ticket:1955]

CHANGES
lib/sqlalchemy/dialects/postgresql/base.py
lib/sqlalchemy/dialects/postgresql/pg8000.py
lib/sqlalchemy/dialects/postgresql/psycopg2.py
test/dialect/test_postgresql.py

diff --git a/CHANGES b/CHANGES
index d7f9dd27692e52e585c662e108b555607dda280d..4f65434559f8269e359c31832f8bb0be80de5b85 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -52,6 +52,11 @@ CHANGES
     version of RowProxy, as well as 2.7 style 
     "collections.Sequence" registration for RowProxy.
     [ticket:1871]
+
+- postgresql
+  - Ensured every numeric, float, int code, scalar + array,
+    are recognized by psycopg2 and pg8000's "numeric" 
+    base type. [ticket:1955]
     
 - mysql
   - Fixed error handling for Jython + zxjdbc, such that 
index 0d103cb0dc9c566e0fe76ac9f81596c0ef959a6a..6eec651b1b0f234b98ea910c20445ec46e834447 100644 (file)
@@ -98,9 +98,9 @@ from sqlalchemy.types import INTEGER, BIGINT, SMALLINT, VARCHAR, \
         CHAR, TEXT, FLOAT, NUMERIC, \
         DATE, BOOLEAN
 
-_DECIMAL_TYPES = (1700, 1231)
+_DECIMAL_TYPES = (1231, 1700)
 _FLOAT_TYPES = (700, 701, 1021, 1022)
-
+_INT_TYPES = (20, 21, 23, 26, 1005, 1007, 1016)
 
 class REAL(sqltypes.Float):
     __visit_name__ = "REAL"
index 6af2cbd76d3ffbb01e113cbbaf7cc6443d85769d..7b1d8e6a7414d52c01f01289724408dfac65404c 100644 (file)
@@ -9,14 +9,16 @@ URLs are of the form
 Unicode
 -------
 
-pg8000 requires that the postgresql client encoding be configured in the postgresql.conf file
-in order to use encodings other than ascii.  Set this value to the same value as 
-the "encoding" parameter on create_engine(), usually "utf-8".
+pg8000 requires that the postgresql client encoding be
+configured in the postgresql.conf file in order to use encodings
+other than ascii. Set this value to the same value as the
+"encoding" parameter on create_engine(), usually "utf-8".
 
 Interval
 --------
 
-Passing data from/to the Interval type is not supported as of yet.
+Passing data from/to the Interval type is not supported as of
+yet.
 
 """
 import decimal
@@ -27,26 +29,28 @@ from sqlalchemy import processors
 from sqlalchemy import types as sqltypes
 from sqlalchemy.dialects.postgresql.base import PGDialect, \
                 PGCompiler, PGIdentifierPreparer, PGExecutionContext,\
-                _DECIMAL_TYPES, _FLOAT_TYPES
+                _DECIMAL_TYPES, _FLOAT_TYPES, _INT_TYPES
 
 class _PGNumeric(sqltypes.Numeric):
     def result_processor(self, dialect, coltype):
         if self.asdecimal:
             if coltype in _FLOAT_TYPES:
                 return processors.to_decimal_processor_factory(decimal.Decimal)
-            elif coltype in _DECIMAL_TYPES:
+            elif coltype in _DECIMAL_TYPES or coltype in _INT_TYPES:
                 # pg8000 returns Decimal natively for 1700
                 return None
             else:
-                raise exc.InvalidRequestError("Unknown PG numeric type: %d" % coltype)
+                raise exc.InvalidRequestError(
+                            "Unknown PG numeric type: %d" % coltype)
         else:
             if coltype in _FLOAT_TYPES:
                 # pg8000 returns float natively for 701
                 return None
-            elif coltype in _DECIMAL_TYPES:
+            elif coltype in _DECIMAL_TYPES or coltype in _INT_TYPES:
                 return processors.to_float
             else:
-                raise exc.InvalidRequestError("Unknown PG numeric type: %d" % coltype)
+                raise exc.InvalidRequestError(
+                            "Unknown PG numeric type: %d" % coltype)
 
 class PGExecutionContext_pg8000(PGExecutionContext):
     pass
index 04b4e1fb76c6d80286a3769c26e5173d60affd79..7c5562064df8d4cabb9d12d4b2044f597fe8d282 100644 (file)
@@ -96,8 +96,9 @@ from sqlalchemy.sql import expression
 from sqlalchemy.sql import operators as sql_operators
 from sqlalchemy import types as sqltypes
 from sqlalchemy.dialects.postgresql.base import PGDialect, PGCompiler, \
-                                            PGIdentifierPreparer, PGExecutionContext, \
-                                            ENUM, ARRAY, _DECIMAL_TYPES, _FLOAT_TYPES
+                                PGIdentifierPreparer, PGExecutionContext, \
+                                ENUM, ARRAY, _DECIMAL_TYPES, _FLOAT_TYPES,\
+                                _INT_TYPES
 
 
 logger = logging.getLogger('sqlalchemy.dialects.postgresql')
@@ -111,19 +112,21 @@ class _PGNumeric(sqltypes.Numeric):
         if self.asdecimal:
             if coltype in _FLOAT_TYPES:
                 return processors.to_decimal_processor_factory(decimal.Decimal)
-            elif coltype in _DECIMAL_TYPES:
+            elif coltype in _DECIMAL_TYPES or coltype in _INT_TYPES:
                 # pg8000 returns Decimal natively for 1700
                 return None
             else:
-                raise exc.InvalidRequestError("Unknown PG numeric type: %d" % coltype)
+                raise exc.InvalidRequestError(
+                            "Unknown PG numeric type: %d" % coltype)
         else:
             if coltype in _FLOAT_TYPES:
                 # pg8000 returns float natively for 701
                 return None
-            elif coltype in _DECIMAL_TYPES:
+            elif coltype in _DECIMAL_TYPES or coltype in _INT_TYPES:
                 return processors.to_float
             else:
-                raise exc.InvalidRequestError("Unknown PG numeric type: %d" % coltype)
+                raise exc.InvalidRequestError(
+                            "Unknown PG numeric type: %d" % coltype)
 
 class _PGEnum(ENUM):
     def __init__(self, *arg, **kw):
index e20274aefa281caa6a76cf3148f03b5781c3ec5e..54127cd9868df76fc537a1a9b7ebfc6b7de75af3 100644 (file)
@@ -456,7 +456,25 @@ class EnumTest(TestBase, AssertsExecutionResults, AssertsCompiledSQL):
             assert t2.c.value2.type.schema == 'test_schema'
         finally:
             metadata.drop_all()
+
+class NumericInterpretationTest(TestBase):
+    
+    
+    def test_numeric_codes(self):
+        from sqlalchemy.dialects.postgresql import pg8000, psycopg2, base
+        from decimal import Decimal
         
+        for dialect in (pg8000.dialect(), psycopg2.dialect()):
+            
+            typ = Numeric().dialect_impl(dialect)
+            for code in base._INT_TYPES + base._FLOAT_TYPES + \
+                        base._DECIMAL_TYPES:
+                proc = typ.result_processor(dialect, code)
+                val = 23.7
+                if proc is not None:
+                    val = proc(val)
+                assert val in (23.7, Decimal("23.7"))
+    
 class InsertTest(TestBase, AssertsExecutionResults):
 
     __only_on__ = 'postgresql'