On databases that don't support time zones -- SQLite, MySQL, Oracle (*) -- the
implementation of time zone support I added in Django 1.4 defines:
1. A global converter, e.g. `parse_datetime_with_timezone_support` for SQLite,
which processes values returned by the database for datetime columns and
returns `datetime.datetime` values. When USE_TZ is True, these are aware
datetimes with a UTC timezone.
This was part of the original patch:
2. A global adapter, e.g. `adapt_datetime_with_timezone_support` for SQLite,
which processes `datetime.datetime` values sent to the database. When
USE_TZ is True, these are converted to UTC, then the tzinfo attribute is
This was introduced to fix #17755:
(*) I believe that Oracle could support time zones like PostgreSQL but Django
doesn't take advantage of this capability at this time.
This is a poor implementation because converters and adapters are global in
the sqlite3 and MySQLdb modules. Other packages such as iPython are affected
I'll keep cx_Oracle outside of this discussion because it has a per-connection
`outputtypehandler` instead of global converters and because Django's Oracle
backend wraps all parameters instead of relying on global adapters.
I think it would be more appropriate to handle all conversions in the ORM.
With the introduction of DatabaseOperations.get_db_converters in Django 1.8,
it seems possible to use per-connection converters instead of global
With this change, `cursor.execute()` will return naive datetimes where it used
to return aware datetimes. That's backwards incompatible, but that's the goal:
Django shouldn't alter globally the behavior of sqlite3 or MySQLdb cursors.
Replacing adapters is a bit more tricky. Removing them causes the two
regression tests for #17755 to fail. I haven't determined how I can process
parameters passed to QuerySet.raw(), but since that's part of the ORM, I'm
With this change, `cursor.execute()` will ignore the time zone of datetimes in
parameters. This looks acceptable for naive datetimes because Django has been
raising a warning for five versions in that case. However it may result in
silent data corruption for aware datetimes with a time zone other than UTC.
Once again that's inherent to the change. Besides documenting it, I don't
have anything to suggest.
In addition to making Django a better citizen in the Python ecosystem, these
changes will make it possible to interact with third-party databases where
data isn't stored in UTC when USE_TZ is True, a big flaw in the current
be a trivial patch once the global converters and adapters are gone.
Do you think the backwards-incompatibilities are acceptable?