From 1fff8daf889822aa1dd9adba19c94bb522d960b4 Mon Sep 17 00:00:00 2001 From: Aymeric Augustin Date: Wed, 8 May 2013 12:57:35 +0200 Subject: [PATCH] Fixed test failures on MySQL. Some tests failed when the time zone definitions were loaded in MySQL and pytz wasn't installed. This setup isn't supported. --- django/db/backends/mysql/base.py | 14 ++++++++++++++ django/db/models/sql/compiler.py | 2 +- docs/ref/models/querysets.txt | 3 ++- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py index d26bd9fd60..d9f66ad5ef 100644 --- a/django/db/backends/mysql/base.py +++ b/django/db/backends/mysql/base.py @@ -30,6 +30,11 @@ if (version < (1, 2, 1) or (version[:3] == (1, 2, 1) and from MySQLdb.converters import conversions, Thing2Literal from MySQLdb.constants import FIELD_TYPE, CLIENT +try: + import pytz +except ImportError: + pytz = None + from django.conf import settings from django.db import utils from django.db.backends import * @@ -186,6 +191,15 @@ class DatabaseFeatures(BaseDatabaseFeatures): @cached_property def has_zoneinfo_database(self): + # MySQL accepts full time zones names (eg. Africa/Nairobi) but rejects + # abbreviations (eg. EAT). When pytz isn't installed and the current + # time zone is LocalTimezone (the only sensible value in this + # context), the current time zone name will be an abbreviation. As a + # consequence, MySQL cannot perform time zone conversions reliably. + if pytz is None: + return False + + # Test if the time zone definitions are installed. cursor = self.connection.cursor() cursor.execute("SELECT 1 FROM mysql.time_zone LIMIT 1") return cursor.fetchone() is not None diff --git a/django/db/models/sql/compiler.py b/django/db/models/sql/compiler.py index 3444b74ac3..018fc098ea 100644 --- a/django/db/models/sql/compiler.py +++ b/django/db/models/sql/compiler.py @@ -1092,7 +1092,7 @@ class SQLDateTimeCompiler(SQLCompiler): if datetime is None: raise ValueError("Database returned an invalid value " "in QuerySet.dates(). Are time zone " - "definitions installed?") + "definitions and pytz installed?") datetime = datetime.replace(tzinfo=None) datetime = timezone.make_aware(datetime, self.query.tzinfo) yield datetime diff --git a/docs/ref/models/querysets.txt b/docs/ref/models/querysets.txt index 3dde0d5411..d27214a66c 100644 --- a/docs/ref/models/querysets.txt +++ b/docs/ref/models/querysets.txt @@ -627,7 +627,8 @@ object. If it's ``None``, Django uses the :ref:`current time zone - SQLite: install pytz_ — conversions are actually performed in Python. - PostgreSQL: no requirements (see `Time Zones`_). - Oracle: no requirements (see `Choosing a Time Zone File`_). - - MySQL: load the time zone tables with `mysql_tzinfo_to_sql`_. + - MySQL: install pytz_ and load the time zone tables with + `mysql_tzinfo_to_sql`_. .. _pytz: http://pytz.sourceforge.net/ .. _Time Zones: http://www.postgresql.org/docs/current/static/datatype-datetime.html#DATATYPE-TIMEZONES