Django DateTimeField() and timezone.now()

你离开我真会死。 提交于 2020-01-13 09:07:33

问题


OK, weird time zone issues when I'm running function tests. Django 1.4, Python 2.7. Are milliseconds truncated in DateTimeField() on MySQL? That's the only theory I've got.

model file

from django.db import models
from django.utils import timezone

class Search(models.Model):
    query = models.CharField(max_length=200, null=True)
    query_date = models.DateTimeField(null=True)

test.py

from django.test import TestCase
from django.utils import timezone
from search.models import Search

class SearchModelTest(TestCase):
def test_creating_a_new_search_and_saving_it_to_the_database(self):
    # start by creating a new Poll object with its "question" set
    search = Search()
    search.query = "Test"
    search.query_date = timezone.now()

    # check we can save it to the database
    search.save()

    # now check we can find it in the database again
    all_search_in_database = Search.objects.all()
    self.assertEquals(len(all_search_in_database), 1)
    only_search_in_database = all_search_in_database[0]
    self.assertEquals(only_search_in_database, search)

    # and check that it's saved its two attributes: question and pub_date
    self.assertEquals(only_search_in_database.query, "Test")
    self.assertEquals(only_search_in_database.query_date, search.query_date)

The test fails with this:

self.assertEquals(only_search_in_database.query_date, search.query_date)
AssertionError: datetime.datetime(2013, 1, 16, 21, 12, 35, tzinfo=<UTC>) != datetime.datetime(2013, 1, 16, 21, 12, 35, 234108, tzinfo=<UTC>)

I think what's happening is that the milliseconds are being truncated after saving to the database. Can that be right? I'm running MySQL v 5.5. Is MySQL truncating the date?


回答1:


Django ORM converts DateTimeField to Timestamp in mysql. You can confirm that by looking at the raw sql doing ./manage.py sqlall <appname>

In mysql timestamp does not store milliseconds.

The TIMESTAMP data type is used for values that contain both date and time parts. TIMESTAMP has a range of '1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC.

It is a bug in MySql which appears to be fixed in v5.6.4, The Bug

Noted in 5.6.4 changelog.

MySQL now supports fractional seconds for TIME, DATETIME, and
TIMESTAMP values, with up to microsecond precision.



回答2:


Django 1.8 now supports milliseconds.

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




回答3:


According to the mysql developer site:

A DATETIME or TIMESTAMP value can include a trailing fractional seconds part in up to microseconds (6 digits) precision. Although this fractional part is recognized, it is discarded from values stored into DATETIME or TIMESTAMP columns.




回答4:


Update: This is really old answer and no longer relevant.

DJango ORM does not yet support microseconds for MySQL. They deliberately truncate the microsecond component. If you are using MySQL 5.6.4 or above, you can apply the following change to DJango code to get this working as expected:

This is a 3 line change. Hope Django developers include it. You can follow the ticket here: https://code.djangoproject.com/ticket/19716


In "db/backends/mysql/base.py"

function "def value_to_db_datetime(self, value)"

Change from:

return six.text_type(value.replace(microseconds=0))

to:

return six.text_type(value)

In "db/backends/mysql/base.py" function "def value_to_db_time(self, value)"

Change from:

return six.text_type(value.replace(microseconds=0))

to:

return six.text_type(value)

In "db/backends/mysql/creation.py" In definition of "data_types"

Change from:

'DateTimeField': 'datetime',

to:

'DateTimeField': 'datetime(6)',


来源:https://stackoverflow.com/questions/14368290/django-datetimefield-and-timezone-now

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!