#12818: sqlite3 backend should use single quotes for string values passed as 
args
to django_date_trunc and django_extract
------------------------------------------+---------------------------------
 Reporter:  lakinwecker                   |       Owner:  nobody    
   Status:  new                           |   Milestone:            
Component:  Database layer (models, ORM)  |     Version:  1.1       
 Keywords:                                |       Stage:  Unreviewed
Has_patch:  0                             |  
------------------------------------------+---------------------------------
 Test case models.py:
 {{{
 from django.db import models

 #------------------------------------------------------------------------------
 class SimpleModel(models.Model):
     month = models.PositiveIntegerField()
     some_date = models.DateTimeField()

 #------------------------------------------------------------------------------
 class SecondModel(models.Model):
     year = models.PositiveIntegerField()
     some_date = models.DateTimeField()

 }}}

 Test case admin.py:
 {{{
 from django.contrib import admin
 from datehierarchy.testbed.models import SimpleModel, SecondModel

 
#-------------------------------------------------------------------------------
 class SimpleModelAdmin(admin.ModelAdmin):
     list_display = ('month', 'some_date',)
     date_hierarchy = 'some_date'

 admin.site.register(SimpleModel, SimpleModelAdmin)


 
#-------------------------------------------------------------------------------
 class SecondModelAdmin(admin.ModelAdmin):
     list_display = ('year', 'some_date',)
     date_hierarchy = 'some_date'

 # Content Models
 admin.site.register(SecondModel, SecondModelAdmin)
 }}}

 Produces tracebacks like this even if valid dates are present:
 {{{
 Traceback:
 File "/home/lakin/Desktop/django/core/handlers/base.py" in get_response
   92.                 response = callback(request, *callback_args,
 **callback_kwargs)
 File "/home/lakin/Desktop/django/contrib/admin/options.py" in wrapper
   226.                 return self.admin_site.admin_view(view)(*args,
 **kwargs)
 File "/home/lakin/Desktop/django/views/decorators/cache.py" in
 _wrapped_view_func
   44.         response = view_func(request, *args, **kwargs)
 File "/home/lakin/Desktop/django/contrib/admin/sites.py" in inner
   186.             return view(request, *args, **kwargs)
 File "/home/lakin/Desktop/django/contrib/admin/options.py" in
 changelist_view
   986.         ], context, context_instance=context_instance)
 File "/home/lakin/Desktop/django/shortcuts/__init__.py" in
 render_to_response
   20.     return HttpResponse(loader.render_to_string(*args, **kwargs),
 **httpresponse_kwargs)
 File "/home/lakin/Desktop/django/template/loader.py" in render_to_string
   108.     return t.render(context_instance)
 File "/home/lakin/Desktop/django/template/__init__.py" in render
   178.         return self.nodelist.render(context)
 File "/home/lakin/Desktop/django/template/__init__.py" in render
   779.                 bits.append(self.render_node(node, context))
 File "/home/lakin/Desktop/django/template/debug.py" in render_node
   71.             result = node.render(context)
 File "/home/lakin/Desktop/django/template/loader_tags.py" in render
   97.         return compiled_parent.render(context)
 File "/home/lakin/Desktop/django/template/__init__.py" in render
   178.         return self.nodelist.render(context)
 File "/home/lakin/Desktop/django/template/__init__.py" in render
   779.                 bits.append(self.render_node(node, context))
 File "/home/lakin/Desktop/django/template/debug.py" in render_node
   71.             result = node.render(context)
 File "/home/lakin/Desktop/django/template/loader_tags.py" in render
   97.         return compiled_parent.render(context)
 File "/home/lakin/Desktop/django/template/__init__.py" in render
   178.         return self.nodelist.render(context)
 File "/home/lakin/Desktop/django/template/__init__.py" in render
   779.                 bits.append(self.render_node(node, context))
 File "/home/lakin/Desktop/django/template/debug.py" in render_node
   71.             result = node.render(context)
 File "/home/lakin/Desktop/django/template/loader_tags.py" in render
   24.         result = self.nodelist.render(context)
 File "/home/lakin/Desktop/django/template/__init__.py" in render
   779.                 bits.append(self.render_node(node, context))
 File "/home/lakin/Desktop/django/template/debug.py" in render_node
   71.             result = node.render(context)
 File "/home/lakin/Desktop/django/template/loader_tags.py" in render
   24.         result = self.nodelist.render(context)
 File "/home/lakin/Desktop/django/template/__init__.py" in render
   779.                 bits.append(self.render_node(node, context))
 File "/home/lakin/Desktop/django/template/debug.py" in render_node
   71.             result = node.render(context)
 File "/home/lakin/Desktop/django/template/__init__.py" in render
   936.                     dict = func(*args)
 File "/home/lakin/Desktop/django/contrib/admin/templatetags/admin_list.py"
 in date_hierarchy
   313.                 } for year in years]
 File "/home/lakin/Desktop/django/db/models/query.py" in _result_iter
   106.                 self._fill_cache()
 File "/home/lakin/Desktop/django/db/models/query.py" in _fill_cache
   692.                     self._result_cache.append(self._iter.next())
 File "/home/lakin/Desktop/django/db/models/sql/subqueries.py" in
 results_iter
   397.                     date = typecast_timestamp(str(date))
 File "/home/lakin/Desktop/django/db/backends/util.py" in
 typecast_timestamp
   68.     if not ' ' in s: return typecast_date(s)
 File "/home/lakin/Desktop/django/db/backends/util.py" in typecast_date
   53.     return s and datetime.date(*map(int, s.split('-'))) or None #
 returns None if s is null

 Exception Type: ValueError at /admin/testbed/secondmodel/
 Exception Value: invalid literal for int() with base 10: 'None'
 }}}

 This is due to the use of double quotes in queries like the following:

 {{{
 SELECT DISTINCT django_date_trunc('year',
 "testbed_secondmodel"."some_date") FROM "testbed_secondmodel" ORDER BY 1
 ASC
 }}}

 Double quotes refer to column names, and int he above test case, the table
 testbed_secondmodel has a column named {{{year}}}, and as such the value
 of {{{year}}} is passed into the the python function
 {{{_sqlite_date_trunc}}} - instead of the string {{{"year"}}}.  Instead,
 if one uses single quotes as per the string constant section in
 http://www.sqlite.org/lang_expr.html - it works just fine.

 Possible patch:


 {{{
 Index: sqlite3/base.py
 ===================================================================
 --- sqlite3/base.py     (revision 12398)
 +++ sqlite3/base.py     (working copy)
 @@ -65,12 +65,12 @@
      def date_extract_sql(self, lookup_type, field_name):
          # sqlite doesn't support extract, so we fake it with the user-
 defined
          # function django_extract that's registered in connect().
 -        return 'django_extract("%s", %s)' % (lookup_type.lower(),
 field_name)
 +        return 'django_extract(\'%s\', %s)' % (lookup_type.lower(),
 field_name)

      def date_trunc_sql(self, lookup_type, field_name):
          # sqlite doesn't support DATE_TRUNC, so we fake it with a user-
 defined
          # function django_date_trunc that's registered in connect().
 -        return 'django_date_trunc("%s", %s)' % (lookup_type.lower(),
 field_name)
 +        return 'django_date_trunc(\'%s\', %s)' % (lookup_type.lower(),
 field_name)

      def drop_foreignkey_sql(self):
          return ""
 }}}

-- 
Ticket URL: <http://code.djangoproject.com/ticket/12818>
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-upda...@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