Fixed #24584 -- Fixed microsecond handling with older MySQLdb

This commit is contained in:
Jon Dufresne 2015-04-04 12:22:30 -07:00 committed by Claude Paroz
parent ad53213066
commit 2cf58e80d1
3 changed files with 30 additions and 5 deletions

View File

@ -77,7 +77,10 @@ class DatabaseOperations(BaseDatabaseOperations):
timedelta.days, timedelta.seconds, timedelta.microseconds), [] timedelta.days, timedelta.seconds, timedelta.microseconds), []
def format_for_duration_arithmetic(self, sql): def format_for_duration_arithmetic(self, sql):
if self.connection.features.supports_microsecond_precision:
return 'INTERVAL %s MICROSECOND' % sql return 'INTERVAL %s MICROSECOND' % sql
else:
return 'INTERVAL FLOOR(%s / 1000000) SECOND' % sql
def drop_foreignkey_sql(self): def drop_foreignkey_sql(self):
return "DROP FOREIGN KEY" return "DROP FOREIGN KEY"
@ -146,6 +149,9 @@ class DatabaseOperations(BaseDatabaseOperations):
else: else:
raise ValueError("MySQL backend does not support timezone-aware datetimes when USE_TZ is False.") raise ValueError("MySQL backend does not support timezone-aware datetimes when USE_TZ is False.")
if not self.connection.features.supports_microsecond_precision:
value = value.replace(microsecond=0)
return six.text_type(value) return six.text_type(value)
def value_to_db_time(self, value): def value_to_db_time(self, value):

View File

@ -21,3 +21,7 @@ Bugfixes
* Fixed :djadmin:`squashmigrations` command when using * Fixed :djadmin:`squashmigrations` command when using
:class:`~django.db.migrations.operations.SeparateDatabaseAndState` :class:`~django.db.migrations.operations.SeparateDatabaseAndState`
(:ticket:`24278`). (:ticket:`24278`).
* Stripped microseconds from ``datetime`` values when using an older version of
the MySQLdb DB API driver as it does not support fractional seconds
(:ticket:`24584`).

View File

@ -192,15 +192,30 @@ class ModelTest(TestCase):
@skipIfDBFeature('supports_microsecond_precision') @skipIfDBFeature('supports_microsecond_precision')
def test_microsecond_precision_not_supported(self): def test_microsecond_precision_not_supported(self):
# In MySQL, microsecond-level precision isn't available. You'll lose # In MySQL, microsecond-level precision isn't always available. You'll
# microsecond-level precision once the data is saved. # lose microsecond-level precision once the data is saved.
a9 = Article( a9 = Article(
headline='Article 9', headline='Article 9',
pub_date=datetime(2005, 7, 31, 12, 30, 45, 180), pub_date=datetime(2005, 7, 31, 12, 30, 45, 180),
) )
a9.save() a9.save()
self.assertEqual(Article.objects.get(id__exact=a9.id).pub_date, self.assertEqual(
datetime(2005, 7, 31, 12, 30, 45)) Article.objects.get(id__exact=a9.id).pub_date,
datetime(2005, 7, 31, 12, 30, 45),
)
@skipIfDBFeature('supports_microsecond_precision')
def test_microsecond_precision_not_supported_edge_case(self):
# In MySQL, microsecond-level precision isn't always available. You'll
# lose microsecond-level precision once the data is saved.
a = Article.objects.create(
headline='Article',
pub_date=datetime(2008, 12, 31, 23, 59, 59, 999999),
)
self.assertEqual(
Article.objects.get(pk=a.pk).pub_date,
datetime(2008, 12, 31, 23, 59, 59),
)
def test_manually_specify_primary_key(self): def test_manually_specify_primary_key(self):
# You can manually specify the primary key when creating a new object. # You can manually specify the primary key when creating a new object.