Django DateTimeField()和timezone.now()

时间:2013-01-16 21:35:18

标签: python django django-models

好的,我正在运行功能测试时出现奇怪的时区问题。 Django 1.4,Python 2.7。在MySQL上的DateTimeField()中是否会截断毫秒数?这是我唯一的理论。

模型文件

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)

测试失败了:

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>)

我认为发生的事情是在保存到数据库后毫秒被截断。那可能是对的吗?我正在运行MySQL v 5.5。 MySQL截断日期吗?

4 个答案:

答案 0 :(得分:11)

Django ORM在mysql中将DateTimeField转换为Timestamp。您可以通过查看执行./manage.py sqlall <appname>

的原始sql来确认

在mysql timestamp中不存储毫秒。

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.

这是MySql中的一个错误,似乎已在v5.6.4中修复,Bug

Noted in 5.6.4 changelog.

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

答案 1 :(得分:5)

Django 1.8现在supports milliseconds

  

以前,当使用MySQL后端时,Django会截断日期时间和时间值的小数秒。现在它让数据库决定是否应该删除该部分值

答案 2 :(得分:2)

根据mysql developer site

  

DATETIME或TIMESTAMP值可以包括尾随小数   秒部分精确到微秒(6位)。虽然这个   小数部分被识别,它从存储的值中被丢弃   DATETIME或TIMESTAMP列。

答案 3 :(得分:-2)

DJango ORM还不支持MySQL的微秒。他们故意截断微秒组件。如果您使用的是MySQL 5.6.4或更高版本,则可以对DJango代码应用以下更改,以使其按预期工作:

这是3行更改。希望Django开发人员包括它。您可以在此处关注此票:https://code.djangoproject.com/ticket/19716


在“db / backends / mysql / base.py”中

function“def value_to_db_datetime(self,value)”

更改自:

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

为:

return six.text_type(value)

在“db / backends / mysql / base.py”中 功能“def value_to_db_time(self,value)”

更改自:

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

为:

return six.text_type(value)

在“db / backends / mysql / creation.py”中 在“data_types”的定义中

更改自:

'DateTimeField': 'datetime',

为:

'DateTimeField': 'datetime(6)',