Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #6767: changed the way the Oracle backend fetches numbers to pr…

…event decimals being returned as floats.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@9750 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit acfe5cc880fe6d11f1c7e0b259be9a885d5d8e66 1 parent f60d0f5
Ian Kelly authored January 15, 2009
1  django/contrib/gis/measure.py
@@ -46,6 +46,7 @@ def default_units(self, kwargs):
46 46
         """
47 47
         val = 0.0
48 48
         for unit, value in kwargs.iteritems():
  49
+            if not isinstance(value, float): value = float(value)
49 50
             if unit in self.UNITS:
50 51
                 val += self.UNITS[unit] * value
51 52
                 default_unit = unit
48  django/db/backends/oracle/base.py
@@ -7,6 +7,7 @@
7 7
 import os
8 8
 import datetime
9 9
 import time
  10
+from decimal import Decimal
10 11
 
11 12
 # Oracle takes client-side character set encoding from the environment.
12 13
 os.environ['NLS_LANG'] = '.UTF8'
@@ -287,6 +288,8 @@ def _cursor(self, settings):
287 288
                 pass
288 289
         if not cursor:
289 290
             cursor = FormatStylePlaceholderCursor(self.connection)
  291
+        # Necessary to retrieve decimal values without rounding error.
  292
+        cursor.numbersAsStrings = True
290 293
         # Default arraysize of 1 is highly sub-optimal.
291 294
         cursor.arraysize = 100
292 295
         return cursor
@@ -390,18 +393,57 @@ def fetchone(self):
390 393
         row = Database.Cursor.fetchone(self)
391 394
         if row is None:
392 395
             return row
393  
-        return tuple([to_unicode(e) for e in row])
  396
+        return self._rowfactory(row)
394 397
 
395 398
     def fetchmany(self, size=None):
396 399
         if size is None:
397 400
             size = self.arraysize
398  
-        return tuple([tuple([to_unicode(e) for e in r])
  401
+        return tuple([self._rowfactory(r)
399 402
                       for r in Database.Cursor.fetchmany(self, size)])
400 403
 
401 404
     def fetchall(self):
402  
-        return tuple([tuple([to_unicode(e) for e in r])
  405
+        return tuple([self._rowfactory(r)
403 406
                       for r in Database.Cursor.fetchall(self)])
404 407
 
  408
+    def _rowfactory(self, row):
  409
+        # Cast numeric values as the appropriate Python type based upon the
  410
+        # cursor description, and convert strings to unicode.
  411
+        casted = []
  412
+        for value, desc in zip(row, self.description):
  413
+            if value is not None and desc[1] is Database.NUMBER:
  414
+                precision, scale = desc[4:6]
  415
+                if scale == -127:
  416
+                    if precision == 0:
  417
+                        # NUMBER column: decimal-precision floating point
  418
+                        # This will normally be an integer from a sequence,
  419
+                        # but it could be a decimal value.
  420
+                        if '.' in value:
  421
+                            value = Decimal(value)
  422
+                        else:
  423
+                            value = int(value)
  424
+                    else:
  425
+                        # FLOAT column: binary-precision floating point.
  426
+                        # This comes from FloatField columns.
  427
+                        value = float(value)
  428
+                elif precision > 0:
  429
+                    # NUMBER(p,s) column: decimal-precision fixed point.
  430
+                    # This comes from IntField and DecimalField columns.
  431
+                    if scale == 0:
  432
+                        value = int(value)
  433
+                    else:
  434
+                        value = Decimal(value)
  435
+                elif '.' in value:
  436
+                    # No type information. This normally comes from a
  437
+                    # mathematical expression in the SELECT list. Guess int
  438
+                    # or Decimal based on whether it has a decimal point.
  439
+                    value = Decimal(value)
  440
+                else:
  441
+                    value = int(value)
  442
+            else:
  443
+                value = to_unicode(value)
  444
+            casted.append(value)
  445
+        return tuple(casted)
  446
+
405 447
 
406 448
 def to_unicode(s):
407 449
     """

0 notes on commit acfe5cc

Please sign in to comment.
Something went wrong with that request. Please try again.