Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Fixed #19360 -- Exception for aggregates on SQLite #637

Closed
wants to merge 1 commit into from

2 participants

Nick Sandford Claude Paroz
Nick Sandford

Raised an explicit exception for aggregates on date/time fields in sqlite3.

Claude Paroz
Owner

Thanks, pushed.

Claude Paroz claudep closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 1 unique commit by 1 author.

Jan 11, 2013
Nick Sandford Fixed #19360 -- Raised an explicit exception for aggregates on date/t…
…ime fields in sqlite3.
227e9fb
This page is out of date. Refresh to see the latest.
14  django/db/backends/sqlite3/base.py
@@ -18,6 +18,8 @@
18 18
 from django.db.backends.sqlite3.client import DatabaseClient
19 19
 from django.db.backends.sqlite3.creation import DatabaseCreation
20 20
 from django.db.backends.sqlite3.introspection import DatabaseIntrospection
  21
+from django.db.models import fields
  22
+from django.db.models.sql import aggregates
21 23
 from django.utils.dateparse import parse_date, parse_datetime, parse_time
22 24
 from django.utils.functional import cached_property
23 25
 from django.utils.safestring import SafeBytes
@@ -127,6 +129,18 @@ def bulk_batch_size(self, fields, objs):
127 129
         limit = 999 if len(fields) > 1 else 500
128 130
         return (limit // len(fields)) if len(fields) > 0 else len(objs)
129 131
 
  132
+    def check_aggregate_support(self, aggregate):
  133
+        # fix for ticket 19360
  134
+        bad_fields = (fields.DateField, fields.DateTimeField, fields.TimeField)
  135
+        bad_aggregates = (aggregates.Sum, aggregates.Avg,
  136
+                          aggregates.Variance, aggregates.StdDev)
  137
+        if isinstance(aggregate.source, bad_fields) and \
  138
+           isinstance(aggregate, bad_aggregates):
  139
+            raise NotImplementedError(
  140
+                'You cannot use Sum, Avg, StdDev and Variance aggregations '
  141
+                'on date/time fields in sqlite3 '
  142
+                'since date/time is saved as text.')
  143
+
130 144
     def date_extract_sql(self, lookup_type, field_name):
131 145
         # sqlite doesn't support extract, so we fake it with the user-defined
132 146
         # function django_extract that's registered in connect(). Note that
8  docs/ref/models/querysets.txt
@@ -2188,6 +2188,14 @@ Django provides the following aggregation functions in the
2188 2188
 aggregate functions, see
2189 2189
 :doc:`the topic guide on aggregation </topics/db/aggregation>`.
2190 2190
 
  2191
+.. warning::
  2192
+
  2193
+        SQLite can't handle aggregation on date/time fields out of the box.
  2194
+        This is because there are no native date/time fields in SQLite and
  2195
+        Django currently emulates these features using a text field.
  2196
+        Attempts to use aggregation on date/time fields in SQLite will
  2197
+        raise ``NotImplementedError``.
  2198
+
2191 2199
 Avg
2192 2200
 ~~~
2193 2201
 
11  tests/regressiontests/backends/models.py
@@ -75,3 +75,14 @@ class Article(models.Model):
75 75
 
76 76
     def __str__(self):
77 77
         return self.headline
  78
+
  79
+
  80
+@python_2_unicode_compatible
  81
+class Item(models.Model):
  82
+    name = models.CharField(max_length=30)
  83
+    date = models.DateField()
  84
+    time = models.TimeField()
  85
+    last_modified = models.DateTimeField()
  86
+
  87
+    def __str__(self):
  88
+        return self.name
18  tests/regressiontests/backends/tests.py
@@ -12,6 +12,7 @@
12 12
     IntegrityError, transaction)
13 13
 from django.db.backends.signals import connection_created
14 14
 from django.db.backends.postgresql_psycopg2 import version as pg_version
  15
+from django.db.models import fields, Sum, Avg, Variance, StdDev
15 16
 from django.db.utils import ConnectionHandler, DatabaseError, load_backend
16 17
 from django.test import (TestCase, skipUnlessDBFeature, skipIfDBFeature,
17 18
     TransactionTestCase)
@@ -362,6 +363,22 @@ def test_parameter_escaping(self):
362 363
         self.assertTrue(int(response))
363 364
 
364 365
 
  366
+class SqlliteAggregationTests(TestCase):
  367
+    """
  368
+    #19360: Raise NotImplementedError when aggregating on date/time fields.
  369
+    """
  370
+    @unittest.skipUnless(connection.vendor == 'sqlite',
  371
+                         "No need to check SQLite aggregation semantics")
  372
+    def test_aggregation(self):
  373
+        for aggregate in (Sum, Avg, Variance, StdDev):
  374
+            self.assertRaises(NotImplementedError,
  375
+                models.Item.objects.all().aggregate, aggregate('time'))
  376
+            self.assertRaises(NotImplementedError,
  377
+                models.Item.objects.all().aggregate, aggregate('date'))
  378
+            self.assertRaises(NotImplementedError,
  379
+                models.Item.objects.all().aggregate, aggregate('last_modified'))
  380
+
  381
+
365 382
 class BackendTestCase(TestCase):
366 383
 
367 384
     def create_squares_with_executemany(self, args):
@@ -400,7 +417,6 @@ def test_cursor_executemany_with_iterator(self):
400 417
             self.create_squares_with_executemany(args)
401 418
         self.assertEqual(models.Square.objects.count(), 9)
402 419
 
403  
-
404 420
     def test_unicode_fetches(self):
405 421
         #6254: fetchone, fetchmany, fetchall return strings as unicode objects
406 422
         qn = connection.ops.quote_name
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.