#10942: Using `select` and `select_params` fails, but using only `select` works,
and the SQL generated for both is identical.
---------------------------------------------------+------------------------
          Reporter:  mrmachine                     |         Owner:  nobody     
               
            Status:  reopened                      |     Milestone:             
               
         Component:  Database layer (models, ORM)  |       Version:  SVN        
               
        Resolution:                                |      Keywords:  extra 
select select_params
             Stage:  Unreviewed                    |     Has_patch:  0          
               
        Needs_docs:  0                             |   Needs_tests:  0          
               
Needs_better_patch:  0                             |  
---------------------------------------------------+------------------------
Changes (by mrmachine):

  * status:  closed => reopened
  * resolution:  invalid =>

Comment:

 After discussion on IRC with Alex, it looks like the problem is that you
 cannot pass a string of comma separated values or an iterable (list of
 PKs) as a param as neither will be properly escaped. The following works
 (using an example taken from the Django source):

 {{{
 >>> from django.contrib.auth.models import User
 >>> params = [1, 3]
 >>> q1 = User.objects.extra(
 ...     select={'featured': 'auth_user.id IN (%s)' % ', '.join(['%s'] *
 len(params))},
 ...     select_params=params
 ... ).values('featured', 'pk', 'username').order_by('-featured', 'pk',
 'username')
 >>> print list(q1)
 [{'username': u'admin', 'pk': 1, 'featured': 1}, {'username': u'manager',
 'pk': 2, 'featured': 0}]
 }}}

 I think that is a bit of a hack. It's not easy to read, and it requires
 the user to flatten any iterators in their list of params and to know the
 number of items in their iterator param, and add an appropriate number of
 '%s' hooks in their SQL.

 Django should know how to properly escape an iterator param, by wrapping
 it in parenthesis, escaping each value and joining with ', '. E.g. the
 following should work:

 {{{
 >>> from django.contrib.auth.models import User
 >>> q1 = User.objects.extra(
 ...     select={'featured': 'auth_user.id IN %s'},
 ...     select_params=[[1, 3]]
 ... ).values('featured', 'pk', 'username').order_by('-featured', 'pk',
 'username')
 >>> print list(q1)
 [{'username': u'admin', 'pk': 1, 'featured': 1}, {'username': u'manager',
 'pk': 2, 'featured': 0}]
 }}}

 But instead, I get:

 {{{
 Traceback (most recent call last):
   File "<console>", line 1, in ?
   File "/path/to/django/db/models/query.py", line 163, in __len__
     self._result_cache.extend(list(self._iter))
   File "/path/to/django/db/models/query.py", line 740, in iterator
     for row in self.query.results_iter():
   File "/path/to/django/db/models/sql/query.py", line 244, in results_iter
     for rows in self.execute_sql(MULTI):
   File "/path/to/django/db/models/sql/query.py", line 1980, in execute_sql
     cursor.execute(sql, params)
   File "/path/to/django/db/backends/util.py", line 19, in execute
     return self.cursor.execute(sql, params)
   File "/path/to/django/db/backends/sqlite3/base.py", line 190, in execute
     return Database.Cursor.execute(self, query, params)
 OperationalError: near "?": syntax error
 }}}

 I'm re-opening this for further consideration as a feature enhancement or
 documentation change. At the very least, the documentation should mention
 that you cannot use an iterator as a param and must flatten your list of
 params and hack the SQL

-- 
Ticket URL: <http://code.djangoproject.com/ticket/10942#comment:2>
Django <http://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to django-updates@googlegroups.com
To unsubscribe from this group, send email to 
django-updates+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to