Ticket #6767: 6767-2.diff

File 6767-2.diff, 3.3 KB (added by Erin Kelly, 16 years ago)

Patch that doesn't remove field-based number formatting of decimal objects.

  • django/db/backends/oracle/base.py

     
    77import os
    88import datetime
    99import time
     10from decimal import Decimal
    1011
    1112# Oracle takes client-side character set encoding from the environment.
    1213os.environ['NLS_LANG'] = '.UTF8'
     
    287288                pass
    288289        if not cursor:
    289290            cursor = FormatStylePlaceholderCursor(self.connection)
     291        # Necessary to retrieve decimal values without rounding error.
     292        cursor.numbersAsStrings = True
    290293        # Default arraysize of 1 is highly sub-optimal.
    291294        cursor.arraysize = 100
    292295        return cursor
     
    390393        row = Database.Cursor.fetchone(self)
    391394        if row is None:
    392395            return row
    393         return tuple([to_unicode(e) for e in row])
     396        return self._rowfactory(row)
    394397
    395398    def fetchmany(self, size=None):
    396399        if size is None:
    397400            size = self.arraysize
    398         return tuple([tuple([to_unicode(e) for e in r])
     401        return tuple([self._rowfactory(r)
    399402                      for r in Database.Cursor.fetchmany(self, size)])
    400403
    401404    def fetchall(self):
    402         return tuple([tuple([to_unicode(e) for e in r])
     405        return tuple([self._rowfactory(r)
    403406                      for r in Database.Cursor.fetchall(self)])
    404407
     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)
    405446
     447
    406448def to_unicode(s):
    407449    """
    408450    Convert strings to Unicode objects (and return all other data types
Back to Top