Code

Opened 8 years ago

Closed 8 years ago

Last modified 8 years ago

#2144 closed defect (fixed)

[patch] parameter conversion failing with get_or_create....

Reported by: matthewharrison@… Owned by: adrian
Component: Database layer (models, ORM) Version:
Severity: normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

I'm having an issue with the get_or_create helper method. Apparently
it isn't coercing parameters properly.

I've got some code that looks like this:

e = Foo(name=name, category=c, display_name=name.capitalize())
e2, created = Foo.objects.get_or_create(name=name, category=c,
display_name=name.capitalize())

The first one will work and the second fails. The issue being that
the category is a foreign key and when creating the Foo object it uses
the id of category. When using the get_or_create method, it passes in
the Category object as the SQL query parameter instead of the id.
Thus giving the following error:

 File "scanfoo.py", line 60, in pop_db
   e2, created = Foo.objects.get_or_create(name=name, category=c,
display_name=name.capitalize())
 File "/home/matt/work/vpython/lib/python2.4/site-packages/Django-0.95-py2.4.egg/django/db/models/manager.py",
line 69, in get_or_create
   return self.get_query_set().get_or_create(*args, **kwargs)
 File "/home/matt/work/vpython/lib/python2.4/site-packages/Django-0.95-py2.4.egg/django/db/models/query.py",
line 217, in get_or_create
   return self.get(**kwargs), False
 File "/home/matt/work/vpython/lib/python2.4/site-packages/Django-0.95-py2.4.egg/django/db/models/query.py",
line 202, in get
   obj_list = list(clone)
 File "/home/matt/work/vpython/lib/python2.4/site-packages/Django-0.95-py2.4.egg/django/db/models/query.py",
line 94, in __iter__
   return iter(self._get_data())
 File "/home/matt/work/vpython/lib/python2.4/site-packages/Django-0.95-py2.4.egg/django/db/models/query.py",
line 412, in _get_data
   self._result_cache = list(self.iterator())
 File "/home/matt/work/vpython/lib/python2.4/site-packages/Django-0.95-py2.4.egg/django/db/models/query.py",
line 163, in iterator
   cursor.execute("SELECT " + (self._distinct and "DISTINCT " or "")
+ ",".join(select) + sql, params)
 File "/home/matt/work/vpython/lib/python2.4/site-packages/Django-0.95-py2.4.egg/django/db/backends/util.py",
line 12, in execute
   return self.cursor.execute(sql, params)
 File "/home/matt/work/vpython/lib/python2.4/site-packages/Django-0.95-py2.4.egg/django/db/backends/sqlite3/base.py",
line 79, in execute
   return Database.Cursor.execute(self, query, params)
pysqlite2.dbapi2.InterfaceError: Error binding parameter 0 - probably
unsupported type.

I've put some debugging statements in to confirm this.

The problem is in query.py line 877 where field.get_db_prep_lookup is called.

Adding the defaults parameter to get_or_create doesn't help either...

Attachments (1)

patch-django-db-models-query_parameter_convertion_#2144 (817 bytes) - added by trbs 8 years ago.

Download all attachments as: .zip

Change History (8)

comment:1 Changed 8 years ago by anonymous

I updated lookup_inner in query.py to workaround this like so...

...
        where.append(get_where_clause(clause, current_table + '.', column, value))
        pvalue = field.get_db_prep_lookup(clause, value)
        pvalue = [_hack_pvalue(x) for x in pvalue]
        params.extend(pvalue)
    return tables, joins, where, params

def _hack_pvalue(value):
    """some foreign keys don't pass the id for some reason...
    force them to"""
    if isinstance(value, django.db.models.Model):
        return value.id
    return value

comment:2 Changed 8 years ago by sjudkins@…

I've resolved it by using the hack above, but any idea when it will be officially fixed in the trunk?

comment:3 Changed 8 years ago by trbs

since Adrians recent rename of 'clause' to 'lookup_type' the above patch broke.
i've updated the patch and diffed it from my development version.

patchname: patch-django-db-models-query_parameter_convertion_#2144

comment:4 Changed 8 years ago by trbs

  • Summary changed from parameter conversion failing with get_or_create.... to [patch] parameter conversion failing with get_or_create....

comment:5 Changed 8 years ago by adrian

This patch is quite hackish -- I wouldn't be comfortable accepting it as-is.

comment:6 Changed 8 years ago by alexis smirnov

tried the similar test with revision 3336 -- appears to work for me

was it fixed by any chance?

comment:7 Changed 8 years ago by trbs

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

Adrian: the patch is very hackish :) and nothing more then an updated version of the org. hack.

Alexis: your right, i've checked the svn with the problem described above and the problem seems to be fixed in changeset 3246,
There russelm commits a much better and cleaner patch in get_db_prep_lookup to lookup the primary key value for an object

I hit this bug from another call then get_or_create (dont remember which one) but with exactly the same results.
Currently i can not reproduce the bug in my application with r3246 or higher.

Closing the ticket for now, since it got resolved way back in r3246 :)
If the patch later turns out to be a solution to a still existing bugn then i'm willing rewrite the patch into something exceptable.

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.