Some time ago I modified the SQLite driver to use SQLite's internal strftime(), instead of using type callbacks. It's mostly straight-forward code, however it did require a small change to core/meta/fields.py to ensure it only generated YY-MM-DD for range searches.
Index: django/core/db/backends/sqlite3.py
===================================================================
--- django/core/db/backends/sqlite3.py (revision 2491)
+++ django/core/db/backends/sqlite3.py (working copy)
@@ -33,9 +33,6 @@
from django.conf.settings import DATABASE_NAME, DEBUG
if self.connection is None:
self.connection = Database.connect(DATABASE_NAME, detect_types=Database.PARSE_DECLTYPES)
- # register extract and date_trun functions
- self.connection.create_function("django_extract", 2, _sqlite_extract)
- self.connection.create_function("django_date_trunc", 2, _sqlite_date_trunc)
cursor = self.connection.cursor(factory=SQLiteCursorWrapper)
cursor.row_factory = utf8rowFactory
if DEBUG:
@@ -88,19 +85,17 @@
# lookup_type is 'year', 'month', 'day'
# sqlite doesn't support extract, so we fake it with the user-defined
# function _sqlite_extract that's registered in connect(), above.
- return 'django_extract("%s", %s)' % (lookup_type.lower(), table_name)
+ strfvals = {
+ 'year': '%%Y',
+ 'month': '%%m',
+ 'day': '%%d',
+ }
+ return 'strftime( %s, "%s" ) ' % ( table_name, strfvals[lookup_type.lower()] )
-def _sqlite_extract(lookup_type, dt):
- try:
- dt = typecasts.typecast_timestamp(dt)
- except (ValueError, TypeError):
- return None
- return str(getattr(dt, lookup_type))
-
def get_date_trunc_sql(lookup_type, field_name):
# lookup_type is 'year', 'month', 'day'
# sqlite doesn't support DATE_TRUNC, so we fake it as above.
- return 'django_date_trunc("%s", %s)' % (lookup_type.lower(), field_name)
+ return 'strftime( "%%%%Y-%%%%m-%%%%d 00:00:00", %s, "start of %s" )' % (field_name, lookup_type.lower())
def get_limit_offset_sql(limit, offset=None):
sql = "LIMIT %s" % limit
@@ -111,18 +106,6 @@
def get_random_function_sql():
return "RANDOM()"
-def _sqlite_date_trunc(lookup_type, dt):
- try:
- dt = typecasts.typecast_timestamp(dt)
- except (ValueError, TypeError):
- return None
- if lookup_type == 'year':
- return "%i-01-01 00:00:00" % dt.year
- elif lookup_type == 'month':
- return "%i-%02i-01 00:00:00" % (dt.year, dt.month)
- elif lookup_type == 'day':
- return "%i-%02i-%02i 00:00:00" % (dt.year, dt.month, dt.day)
-
def get_table_list(cursor):
cursor.execute("SELECT name FROM sqlite_master WHERE type='table' ORDER BY name")
return [row[0] for row in cursor.fetchall()]
Index: django/core/meta/fields.py
===================================================================
--- django/core/meta/fields.py (revision 2491)
+++ django/core/meta/fields.py (working copy)
@@ -389,7 +389,7 @@
def get_db_prep_lookup(self, lookup_type, value):
if lookup_type == 'range':