#30770: annotating  TruncBase on ExpressionWrapper for date arithmetic, causes
unnecessary  placeholder "%s" escaping to "%%s" and TypeError
-------------------------------------+-------------------------------------
     Reporter:  Jurgis Pralgauskis   |                    Owner:  nobody
         Type:  Bug                  |                   Status:  new
    Component:  Database layer       |                  Version:  1.11
  (models, ORM)                      |
     Severity:  Normal               |               Resolution:
     Keywords:  TruncBase, DateTime  |             Triage Stage:
  arithmetics,                       |  Unreviewed
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------

Old description:

> I tried:
> {{{#!python
> from django.db.models import F,  DateTimeField, ExpressionWrapper
> from django.db.models.functions import Cast, Least, Greatest, Now,
> Coalesce, ExtractWeekDay, TruncDay
> User.objects
>    .annotate(trial_end=TruncDay(ExpressionWrapper(F('date_joined')+
> timedelta(days=30), output_field=DateTimeField())))
>    .values('id', 'date_joined', 'trial_end')[:3]
> )
> }}}
>
> and got
> {{{
> Traceback (most recent call last):
>   File "<input>", line 3, in <module>
>   File "lib/python3.4/site-packages/django/db/models/query.py", line 226,
> in __repr__
>     data = list(self[:REPR_OUTPUT_SIZE + 1])
>   File "lib/python3.4/site-packages/django/db/models/query.py", line 250,
> in __iter__
>     self._fetch_all()
>   File "lib/python3.4/site-packages/django/db/models/query.py", line
> 1118, in _fetch_all
>     self._result_cache = list(self._iterable_class(self))
>   File "lib/python3.4/site-packages/django/db/models/query.py", line 106,
> in __iter__
>     for row in compiler.results_iter():
>   File "lib/python3.4/site-packages/django/db/models/sql/compiler.py",
> line 836, in results_iter
>     results = self.execute_sql(MULTI)
>   File "lib/python3.4/site-packages/django/db/models/sql/compiler.py",
> line 894, in execute_sql
>     raise original_exception
>   File "lib/python3.4/site-packages/django/db/models/sql/compiler.py",
> line 884, in execute_sql
>     cursor.execute(sql, params)
>   File "lib/python3.4/site-packages/django/db/backends/utils.py", line
> 80, in execute
>     return super(CursorDebugWrapper, self).execute(sql, params)
>   File "lib/python3.4/site-packages/django/db/backends/utils.py", line
> 65, in execute
>     return self.cursor.execute(sql, params)
> TypeError: not all arguments converted during string formatting
> }}}
>

> and
>
> {{{#!python
>  qs.query.sql_with_params()[0]
> }}}
>
> shows
>
> {{{#!sql
> 'SELECT "ta_account"."id", "ta_account"."date_joined",
> DATE_TRUNC(\'day\', ("ta_account"."date_joined" + %%s) AT TIME ZONE %s)
> AS "trial_end" FROM "ta_account" LIMIT 3'
> }}}
>
> notice **%%s** -- that causes problem..

New description:

 I tried:
 {{{#!python
 from django.db.models import F,  DateTimeField, ExpressionWrapper
 from django.db.models.functions import Cast, Least, Greatest, Now,
 Coalesce, ExtractWeekDay, TruncDay

 User.objects
    .annotate(trial_end=TruncDay(ExpressionWrapper(F('date_joined')+
 timedelta(days=30), output_field=DateTimeField())))
    .values('id', 'date_joined', 'trial_end')[:3]
 )
 }}}

 and got
 {{{
 Traceback (most recent call last):
   File "<input>", line 3, in <module>
   File "lib/python3.4/site-packages/django/db/models/query.py", line 226,
 in __repr__
     data = list(self[:REPR_OUTPUT_SIZE + 1])
   File "lib/python3.4/site-packages/django/db/models/query.py", line 250,
 in __iter__
     self._fetch_all()
   File "lib/python3.4/site-packages/django/db/models/query.py", line 1118,
 in _fetch_all
     self._result_cache = list(self._iterable_class(self))
   File "lib/python3.4/site-packages/django/db/models/query.py", line 106,
 in __iter__
     for row in compiler.results_iter():
   File "lib/python3.4/site-packages/django/db/models/sql/compiler.py",
 line 836, in results_iter
     results = self.execute_sql(MULTI)
   File "lib/python3.4/site-packages/django/db/models/sql/compiler.py",
 line 894, in execute_sql
     raise original_exception
   File "lib/python3.4/site-packages/django/db/models/sql/compiler.py",
 line 884, in execute_sql
     cursor.execute(sql, params)
   File "lib/python3.4/site-packages/django/db/backends/utils.py", line 80,
 in execute
     return super(CursorDebugWrapper, self).execute(sql, params)
   File "lib/python3.4/site-packages/django/db/backends/utils.py", line 65,
 in execute
     return self.cursor.execute(sql, params)
 TypeError: not all arguments converted during string formatting
 }}}


 and

 {{{#!python
  qs.query.sql_with_params()[0]
 }}}

 shows

 {{{#!sql
 'SELECT "ta_account"."id", "ta_account"."date_joined", DATE_TRUNC(\'day\',
 ("ta_account"."date_joined" + %%s) AT TIME ZONE %s) AS "trial_end" FROM
 "ta_account" LIMIT 3'
 }}}

 notice **%%s** -- that causes problem..

--

Comment (by Jurgis Pralgauskis):

 ps.:
 here one can workaround by exchanging TruncDay with ExpressionWrapper:
 {{{#!python
 trial_end=ExpressionWrapper(TruncDay('date_joined')+ timedelta(days=30))
 }}}

 But my situation was more complex (I was doing arithmetics in minutes and
 applying TruncDay few steps later )

-- 
Ticket URL: <https://code.djangoproject.com/ticket/30770#comment:1>
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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/061.30529f67feb971a1435900283d8316cc%40djangoproject.com.

Reply via email to