Django

Code

Ticket #1468 (closed: wontfix)

Opened 4 years ago

Last modified 3 years ago

[patch] SQLite patch to use internal date conversion functions

Reported by: mildly@abnormal.com Assigned to: adrian
Milestone: Component: Database layer (models, ORM)
Version: Keywords: sqlite
Cc: Triage Stage: Design decision needed
Has patch: 1 Needs documentation: 0
Needs tests: 1 Patch needs improvement: 0

Description

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':                                                                                                  

Attachments

sqlite.patch (3.0 kB) - added by mildly@abnormal.com on 03/07/06 19:57:57.

Change History

03/06/06 18:14:56 changed by Malcolm Tredinnick <malcolm@pointy-stick.com>

Is this patch complete? It looks like the chunk for django/core/meta/fields.py got cut off (there are no changes in it). Also, please attach the patch as an attachment, rather than including the text in the body so that it is easier to test and apply.

03/07/06 19:57:57 changed by mildly@abnormal.com

  • attachment sqlite.patch added.

03/07/06 19:59:12 changed by mildly@abnormal.com

My appologies. Didn't notice the attach button there.

06/12/06 06:09:45 changed by Go

  • type changed from enhancement to defect.

01/17/07 22:56:31 changed by Simon G. <dev@simon.net.nz>

  • keywords set to sqlite.
  • has_patch set to 1.
  • needs_tests set to 1.

01/17/07 22:56:42 changed by Simon G. <dev@simon.net.nz>

  • summary changed from SQLite patch to use internal date conversion functions to [patch] SQLite patch to use internal date conversion functions.

01/23/07 05:05:45 changed by Simon G. <dev@simon.net.nz>

  • stage changed from Unreviewed to Design decision needed.

03/10/07 05:03:23 changed by mtredinnick

  • status changed from new to closed.
  • resolution set to wontfix.

Since the "range" query can take full datetime objects (including times, not just dates), we can't restrict it to just querying on year/month/day triples.


Add/Change #1468 ([patch] SQLite patch to use internal date conversion functions)




Change Properties
Action