#26824 closed Bug (invalid)
MySQL query with CONVERT_TZ is not properly formated
Reported by: | Luboš Truhlář | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 1.9 |
Severity: | Normal | Keywords: | mysql, timezone |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Hi,
I think that there is a bug in ORM if queryset using 'date' and TIMEZONE.
This code:
queryset = queryset.filter(created_at__date__lte=created_at_to.date())
produces this SQL query:
SELECT ... FROM `payments_payment` WHERE DATE(CONVERT_TZ(`payments_payment`.`created_at`, 'UTC', Europe/Prague)) <= 2016-06-30)
The problem is that 'Europe/Prague' is not in the quotes! Mysql returns this error:
#1054 - Unknown column 'Europe' in 'where clause'
my settings.py
TIME_ZONE = "Europe/Prague" DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'reality_15062016', 'PORT': '3306', 'TIME_ZONE': 'Europe/Prague', 'OPTIONS': { 'charset': 'utf8', 'use_unicode': True, } } }
Change History (8)
comment:1 by , 8 years ago
comment:2 by , 8 years ago
Using Mysql: 5.5.49-0+deb8u1 - (Debian)
MySQL timezone definitions have been loaded properly.
Strange behavior. I pass all 6 tests in the suite, which you point. But when I try the single SQL query, the Error appears.
I modified the code a little to see the query which Django produce.
... with self.settings(TIME_ZONE='UTC'): # But in UTC, the __date only matches one of them. q = DateTimeModel.objects.filter(dt__date=d) print q.query self.assertQuerysetEqual(DateTimeModel.objects.filter(dt__date=d), [repr(m1)])
and the output is this:
Using existing test database for alias 'default'... .sSELECT `payments_datetimemodel`.`id`, `payments_datetimemodel`.`d`, `payments_datetimemodel`.`dt`, `payments_datetimemodel`.`t` FROM `payments_datetimemodel` WHERE DATE(CONVERT_TZ(`payments_datetimemodel`.`dt`, 'UTC', UTC)) = 2014-03-12 .... ---------------------------------------------------------------------- Ran 6 tests in 0.734s OK (skipped=1)
Then trying to use the same query (without quotes) directly in mysql client.
mysql> SELECT `payments_datetimemodel`.`id`, `payments_datetimemodel`.`d`, `payments_datetimemodel`.`dt`, `payments_datetimemodel`.`t` FROM `payments_datetimemodel` WHERE DATE(CONVERT_TZ(`payments_datetimemodel`.`dt`, 'UTC', UTC)) = 2014-03-12; ERROR 1054 (42S22): Unknown column 'UTC' in 'where clause'
and with quotes:
mysql> SELECT `payments_datetimemodel`.`id`, `payments_datetimemodel`.`d`, `payments_datetimemodel`.`dt`, `payments_datetimemodel`.`t` FROM `payments_datetimemodel` WHERE DATE(CONVERT_TZ(`payments_datetimemodel`.`dt`, 'UTC', 'UTC')) = 2014-03-12; Empty set (0.00 sec)
follow-up: 5 comment:3 by , 8 years ago
str(queryset.query)
returns a representation of the query, not necessarily one that can be executed. Is that the issue in the original report?
comment:4 by , 8 years ago
Resolution: | → needsinfo |
---|---|
Status: | new → closed |
comment:5 by , 8 years ago
No, it's not the issue, which I wan't to report. My issue is that the '_date' filter is not working correctly in my configuration.
Replying to timgraham:
str(queryset.query)
returns a representation of the query, not necessarily one that can be executed. Is that the issue in the original report?
follow-up: 7 comment:6 by , 8 years ago
What did you use to print the query you pasted into the mysql client?
comment:7 by , 8 years ago
queryset = Payments.objects.filter(created_at__date__lte=created_at_to.date()) print queryset.query
Replying to charettes:
What did you use to print the query you pasted into the mysql client?
comment:8 by , 8 years ago
Resolution: | needsinfo → invalid |
---|
As mentioned by Tim above str(queryset.query)
returns a representation of the query and not what is actually executed as the escaping part is left to the backend which escapes parameters such as the timezone name.
Please re-open if you can provide an actual failing testcase or at least a traceback that does not rely on executing a representation of Queryset.query
.
Can you try to construct a test for Django's test suite? A found a similar one which generates this query:
Does it pass for you? Which version of MySQL are you using?
Did you load the MySQL timezone definitions?