#25287: Multiplying and dividing connectors for datetime expressions are not
supported by sqlite backed.
-------------------------------------+-------------------------------------
     Reporter:  Ahmet DAL            |                    Owner:  nobody
         Type:  New feature          |                   Status:  new
    Component:  Database layer       |                  Version:  3.0
  (models, ORM)                      |
     Severity:  Normal               |               Resolution:
     Keywords:  sqlite3,             |             Triage Stage:  Accepted
  combine_duration_expression, F     |
  expressions,                       |
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
Changes (by Baptiste Mispelon):

 * version:  1.8 => 3.0


Comment:

 I was able to reproduce the reported error on the latest master
 (a5855c8f0fe17b7e888bd8137874ef78012a7294) by using the following models:
 {{{
 #!python
 from django.db import models


 class Ticket(models.Model):
     date_opened = models.DateTimeField()


 class Rule(models.Model):
     duration = models.DurationField()


 class Action(models.Model):
     percent = models.FloatField()
     rule = models.ForeignKey('Rule', on_delete=models.CASCADE)


 class Expire(models.Model):
     ticket = models.ForeignKey('Ticket', on_delete=models.CASCADE)
     action = models.ForeignKey('Action', on_delete=models.CASCADE)
 }}}

 And the following testcase:
 {{{
 #!python
 from datetime import timedelta

 from django.db.models import F
 from django.test import TestCase
 from django.utils import timezone

 from .models import Ticket, Rule, Action, Expire


 class TicketTestCase(TestCase):
     def test_ticket(self):
         now = timezone.now()

         ticket1 = Ticket.objects.create(date_opened=now-timedelta(days=6))
         ticket2 = Ticket.objects.create(date_opened=now-timedelta(days=4))

         rule = Rule.objects.create(duration=timedelta(days=10))
         action = Action.objects.create(rule=rule, percent=50)

         expire = Expire.objects.create(ticket=ticket1, action=action)
         expire = Expire.objects.create(ticket=ticket2, action=action)


         qs =
 Expire.objects.filter(ticket__date_opened__lte=(timezone.now() -
 F("action__percent") * F("action__rule__duration") / 100))
         self.assertQuerysetEqual(qs, [ticket1.pk], transform=lambda x:
 x.ticket.pk)
 }}}

 As described in the original ticket, the testcase fails with sqlite
 (`DatabaseError: Invalid connector for timedelta: *.`) but passes when
 using postgresql.

 The proposed solution of adding the new `*` and `/` operators to
 `sqlite3.DatebaseOperations.combine_duration_expression()` [1] only works
 in that the `DatebaseError` disappears but the test still fails because
 the returned queryset is empty.

 Josh's suggestions of wrapping everything in an `ExpressionWrapper` don't
 seem to make a difference either.



 [1]
 
https://github.com/django/django/blob/a5855c8f0fe17b7e888bd8137874ef78012a7294/django/db/backends/sqlite3/operations.py#L315

-- 
Ticket URL: <https://code.djangoproject.com/ticket/25287#comment:7>
Django <https://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 unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/066.08c1cf15111d06ccbbfcc9b6b9d09e1f%40djangoproject.com.

Reply via email to