mirror of https://github.com/django/django.git
Fixed #19716 -- Added support for microseconds with MySQL 5.6.4 and up
Thanks erik@cederstrand.dk for the report and Tim Graham for the review.
This commit is contained in:
parent
9e746c13e8
commit
22da5f8817
|
@ -79,7 +79,7 @@ def adapt_datetime_with_timezone_support(value, conv):
|
||||||
default_timezone = timezone.get_default_timezone()
|
default_timezone = timezone.get_default_timezone()
|
||||||
value = timezone.make_aware(value, default_timezone)
|
value = timezone.make_aware(value, default_timezone)
|
||||||
value = value.astimezone(timezone.utc).replace(tzinfo=None)
|
value = value.astimezone(timezone.utc).replace(tzinfo=None)
|
||||||
return Thing2Literal(value.strftime("%Y-%m-%d %H:%M:%S"), conv)
|
return Thing2Literal(value.strftime("%Y-%m-%d %H:%M:%S.%f"), conv)
|
||||||
|
|
||||||
# MySQLdb-1.2.1 returns TIME columns as timedelta -- they are more like
|
# MySQLdb-1.2.1 returns TIME columns as timedelta -- they are more like
|
||||||
# timedelta in terms of actual behavior as they are signed and include days --
|
# timedelta in terms of actual behavior as they are signed and include days --
|
||||||
|
@ -175,7 +175,6 @@ class DatabaseFeatures(BaseDatabaseFeatures):
|
||||||
supports_forward_references = False
|
supports_forward_references = False
|
||||||
# XXX MySQL DB-API drivers currently fail on binary data on Python 3.
|
# XXX MySQL DB-API drivers currently fail on binary data on Python 3.
|
||||||
supports_binary_field = six.PY2
|
supports_binary_field = six.PY2
|
||||||
supports_microsecond_precision = False
|
|
||||||
supports_regex_backreferencing = False
|
supports_regex_backreferencing = False
|
||||||
supports_date_lookup_using_string = False
|
supports_date_lookup_using_string = False
|
||||||
can_introspect_binary_field = False
|
can_introspect_binary_field = False
|
||||||
|
@ -210,6 +209,10 @@ class DatabaseFeatures(BaseDatabaseFeatures):
|
||||||
"Confirm support for introspected foreign keys"
|
"Confirm support for introspected foreign keys"
|
||||||
return self._mysql_storage_engine != 'MyISAM'
|
return self._mysql_storage_engine != 'MyISAM'
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def supports_microsecond_precision(self):
|
||||||
|
return self.connection.mysql_version >= (5, 6, 4)
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def has_zoneinfo_database(self):
|
def has_zoneinfo_database(self):
|
||||||
# MySQL accepts full time zones names (eg. Africa/Nairobi) but rejects
|
# MySQL accepts full time zones names (eg. Africa/Nairobi) but rejects
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from django.db.backends.creation import BaseDatabaseCreation
|
from django.db.backends.creation import BaseDatabaseCreation
|
||||||
|
from django.utils.functional import cached_property
|
||||||
|
|
||||||
|
|
||||||
class DatabaseCreation(BaseDatabaseCreation):
|
class DatabaseCreation(BaseDatabaseCreation):
|
||||||
|
@ -6,7 +7,7 @@ class DatabaseCreation(BaseDatabaseCreation):
|
||||||
# types, as strings. Column-type strings can contain format strings; they'll
|
# types, as strings. Column-type strings can contain format strings; they'll
|
||||||
# be interpolated against the values of Field.__dict__ before being output.
|
# be interpolated against the values of Field.__dict__ before being output.
|
||||||
# If a column type is set to None, it won't be included in the output.
|
# If a column type is set to None, it won't be included in the output.
|
||||||
data_types = {
|
_data_types = {
|
||||||
'AutoField': 'integer AUTO_INCREMENT',
|
'AutoField': 'integer AUTO_INCREMENT',
|
||||||
'BinaryField': 'longblob',
|
'BinaryField': 'longblob',
|
||||||
'BooleanField': 'bool',
|
'BooleanField': 'bool',
|
||||||
|
@ -33,6 +34,13 @@ class DatabaseCreation(BaseDatabaseCreation):
|
||||||
'UUIDField': 'char(32)',
|
'UUIDField': 'char(32)',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def data_types(self):
|
||||||
|
if self.connection.features.supports_microsecond_precision:
|
||||||
|
return dict(self._data_types, DateTimeField='datetime(6)', TimeField='time(6)')
|
||||||
|
else:
|
||||||
|
return self._data_types
|
||||||
|
|
||||||
def sql_table_creation_suffix(self):
|
def sql_table_creation_suffix(self):
|
||||||
suffix = []
|
suffix = []
|
||||||
test_settings = self.connection.settings_dict['TEST']
|
test_settings = self.connection.settings_dict['TEST']
|
||||||
|
|
|
@ -496,11 +496,32 @@ for the field. This affects :class:`~django.db.models.CharField`,
|
||||||
:class:`~django.db.models.SlugField` and
|
:class:`~django.db.models.SlugField` and
|
||||||
:class:`~django.db.models.CommaSeparatedIntegerField`.
|
:class:`~django.db.models.CommaSeparatedIntegerField`.
|
||||||
|
|
||||||
DateTime fields
|
.. _mysql-fractional-seconds:
|
||||||
~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
MySQL does not store fractions of seconds. Fractions of seconds are truncated
|
Fractional seconds support for Time and DateTime fields
|
||||||
to zero when the time is stored.
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
MySQL 5.6.4 and later can store fractional seconds, provided that the
|
||||||
|
column definition includes a fractional indication (e.g. ``DATETIME(6)``).
|
||||||
|
Earlier versions do not support them at all.
|
||||||
|
|
||||||
|
Django will not upgrade existing columns to include fractional seconds if the
|
||||||
|
database server supports it. If you want to enable them on an existing database,
|
||||||
|
it's up to you to either manually update the column on the target database, by
|
||||||
|
executing a command like::
|
||||||
|
|
||||||
|
ALTER TABLE `your_table` MODIFY `your_datetime_column` DATETIME(6)
|
||||||
|
|
||||||
|
or using a :class:`~django.db.migrations.operations.RunSQL` operation in a
|
||||||
|
:ref:`data migration <data-migrations>`.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.8
|
||||||
|
|
||||||
|
Previously, Django truncated fractional seconds from ``datetime`` and
|
||||||
|
``time`` values when using the MySQL backend. Now it lets the database
|
||||||
|
decide whether it should drop that part of the value or not. By default, new
|
||||||
|
``DateTimeField`` or ``TimeField`` columns are now created with fractional
|
||||||
|
seconds support on MySQL 5.6.4 or later.
|
||||||
|
|
||||||
``TIMESTAMP`` columns
|
``TIMESTAMP`` columns
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
|
@ -166,7 +166,9 @@ Database backends
|
||||||
* The MySQL backend no longer strips microseconds from ``datetime`` values as
|
* The MySQL backend no longer strips microseconds from ``datetime`` values as
|
||||||
MySQL 5.6.4 and up supports fractional seconds depending on the declaration
|
MySQL 5.6.4 and up supports fractional seconds depending on the declaration
|
||||||
of the datetime field (when ``DATETIME`` includes fractional precision greater
|
of the datetime field (when ``DATETIME`` includes fractional precision greater
|
||||||
than 0).
|
than 0). New datetime database columns created with Django 1.8 and MySQL 5.6.4
|
||||||
|
and up will support microseconds. See the :ref:`MySQL database notes
|
||||||
|
<mysql-fractional-seconds>` for more details.
|
||||||
|
|
||||||
Email
|
Email
|
||||||
^^^^^
|
^^^^^
|
||||||
|
|
Loading…
Reference in New Issue