Code

Opened 4 years ago

Closed 4 years ago

#12402 closed (fixed)

QuerySet.defer does not work properly on Oracle

Reported by: jtiai 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\Prompts.py", line 552, in __call__
    manipulated_val = self.display(arg)
  File "C:\Python25\lib\site-packages\IPython\Prompts.py", line 578, in _display
    return self.shell.hooks.result_display(arg)
  File "C:\Python25\lib\site-packages\IPython\hooks.py", line 141, in __call__
    ret = cmd(*args, **kw)
  File "C:\Python25\lib\site-packages\IPython\hooks.py", line 171, in result_display
    out = pformat(arg)
  File "C:\Python25\lib\pprint.py", line 111, in pformat
    self._format(object, sio, 0, 0, {}, 0)
  File "C:\Python25\lib\pprint.py", line 129, in _format
    rep = self._repr(object, context, level - 1)
  File "C:\Python25\lib\pprint.py", line 195, in _repr
    self._depth, level)
  File "C:\Python25\lib\pprint.py", line 207, in format
    return _safe_repr(object, context, maxlevels, level)
  File "C:\Python25\lib\pprint.py", line 292, in _safe_repr
    rep = repr(object)
  File "C:\django\trunk\django\db\models\query.py", line 61, in __repr__
    data = list(self[:REPR_OUTPUT_SIZE + 1])
  File "C:\django\trunk\django\db\models\query.py", line 76, in __len__
    self._result_cache.extend(list(self._iter))
  File "C:\django\trunk\django\db\models\query.py", line 261, in iterator
    for row in self.query.results_iter():
  File "C:\django\trunk\django\db\models\sql\query.py", line 292, in results_iter
    row = self.resolve_columns(row, fields)
  File "C:\django\trunk\django\db\backends\oracle\query.py", line 54, in resolve_columns
    values.append(self.convert_values(value, field))
  File "C:\django\trunk\django\db\backends\oracle\query.py", 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 4 years ago.

Download all attachments as: .zip

Change History (5)

comment:1 Changed 4 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 changed from Deferring geometry field causes invalid results or crash to Deferring geometry field does not work on Oracle

This problem only affects the Oracle spatial backend.

comment:2 Changed 4 years ago by jbronn

  • Component changed from GIS to Database layer (models, ORM)
  • Description modified (diff)
  • Keywords defer added; gis removed
  • Status changed from new to assigned
  • Summary changed from Deferring geometry field does not work on Oracle to QuerySet.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 4 years ago by jbronn

  • Description modified (diff)

Changed 4 years ago by jbronn

comment:4 Changed 4 years ago by jbronn

  • Resolution set to fixed
  • Status changed from assigned to closed

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

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.