Opened 7 years ago

Closed 7 years ago

#12402 closed (fixed)

QuerySet.defer does not work properly on Oracle

Reported by: Jani Tiainen Owned by: jbronn
Component: Database layer (models, ORM) Version: master
Severity: Keywords: orm oracle defer
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description (last modified by jbronn)

The machinery in OracleQuery.resolve_columns does not take into account any fields that are deferred. Seeing this error depends on the order of the fields, and how they are handled by OracleQuery.convert_values -- which is probably why it's missed in the test suite. Here's an example model that demonstrates the problem:

from django.db import models

class MyModel(models.Model):
     num = models.FloatField()
     name = models.CharField(max_length=128)

Here's how to raise it:

>>> MyModel.objects.create(num=5.0, name='Foobar')
<MyModel: MyModel object>
>>> qs = MyModel.objects.defer('num')
>>> print qs
Traceback (most recent call last):
  File "<ipython console>", line 1, in <module>
  File "C:\Python25\lib\site-packages\IPython\", line 552, in __call__
    manipulated_val = self.display(arg)
  File "C:\Python25\lib\site-packages\IPython\", line 578, in _display
  File "C:\Python25\lib\site-packages\IPython\", line 141, in __call__
    ret = cmd(*args, **kw)
  File "C:\Python25\lib\site-packages\IPython\", line 171, in result_display
    out = pformat(arg)
  File "C:\Python25\lib\", line 111, in pformat
    self._format(object, sio, 0, 0, {}, 0)
  File "C:\Python25\lib\", line 129, in _format
    rep = self._repr(object, context, level - 1)
  File "C:\Python25\lib\", line 195, in _repr
    self._depth, level)
  File "C:\Python25\lib\", line 207, in format
    return _safe_repr(object, context, maxlevels, level)
  File "C:\Python25\lib\", line 292, in _safe_repr
    rep = repr(object)
  File "C:\django\trunk\django\db\models\", line 61, in __repr__
    data = list(self[:REPR_OUTPUT_SIZE + 1])
  File "C:\django\trunk\django\db\models\", line 76, in __len__
  File "C:\django\trunk\django\db\models\", line 261, in iterator
    for row in self.query.results_iter():
  File "C:\django\trunk\django\db\models\sql\", line 292, in results_iter
    row = self.resolve_columns(row, fields)
  File "C:\django\trunk\django\db\backends\oracle\", line 54, in resolve_columns
    values.append(self.convert_values(value, field))
  File "C:\django\trunk\django\db\backends\oracle\", line 74, in convert_values
    value = float(value)
ValueError: invalid literal for float(): Foobar

The problem reveals itself here because although we've deferred the FloatField, it's instance is still passed into convert_values with the value associated with the CharField.

Attachments (1)

defer_resolve_columns_fix_v1.diff (2.2 KB) - added by jbronn 7 years ago.

Download all attachments as: .zip

Change History (5)

comment:1 Changed 7 years ago by jbronn

Keywords: oracle gis added
Needs documentation: unset
Needs tests: unset
Owner: changed from nobody to jbronn
Patch needs improvement: unset
Summary: Deferring geometry field causes invalid results or crashDeferring geometry field does not work on Oracle

This problem only affects the Oracle spatial backend.

comment:2 Changed 7 years ago by jbronn

Component: GISDatabase layer (models, ORM)
Description: modified (diff)
Keywords: defer added; gis removed
Status: newassigned
Summary: Deferring geometry field does not work on OracleQuerySet.defer does not work properly on Oracle

The problem is not GeoDjango related at all, and applies to the entire Oracle backend.

comment:3 Changed 7 years ago by jbronn

Description: modified (diff)

Changed 7 years ago by jbronn

comment:4 Changed 7 years ago by jbronn

Resolution: fixed
Status: assignedclosed

(In [11911]) [soc2009/multidb] Fixed #12402 -- QuerySet.defer now interacts properly with SQLCompiler subclasses that implement resolve_columns.

Note: See TracTickets for help on using tickets.
Back to Top