Django - Mysql datetime timezone天真且有意识

时间:2014-05-20 09:30:12

标签: python mysql django datetime timezone

我参与将应用程序从php - mysql迁移到django - mysql,好吧,我已经开始迁移一个收件箱应用程序,它允许用户在我第一次数据迁移后使用插件发送消息1to1(使用插入 - 选择mysql声明)我继续进行一些数据迁移,如下所示。

  • 我尝试迁移消息状态:在我的“遗留”数据库中,使用的方法是使用带有整数的按位字段,例如1表示接收,2表示读取,4表示垃圾等等,我已经安装了django -bitwise来完成相同的方法,但我必须将这些整数迁移到像“RECEIVED”,“READ”,“TRASH”这样的字符串......由于我有数百万行,所以我不能将ORM与objects.all()和我已经决定逐月去。

如果我尝试使用以下ORM语句按月计算消息:

Message.objects.filter(sent_at__year=2011, sent_at__month=1).count()

返回0


如果我使用以下SQL语句直接计算它,则返回正确的数字:

select count(*) 
from inbox_message 
where year(sent_at) = 2011 and month(sent_at) = 1;

结果是64955


经过一些挖掘Google和Stackoverflow后,它似乎与时区天真的日期时间有关,所以我尝试了以下

settings.USE_TZ = False
Message.objects.filter(sent_at__year=2011, sent_at__month=1).count()

现在返回64955万岁!


众所周知,我已经开始将'sent_at'从时区转换为时区感知,我的第一种方法是在我的insert - select语句中应用CONVERT_TZ mysql函数,但它产生相同的结果,因为我的原始数据源在UTC + 1时区我决定使用以下方法解决这个问题:

convert_tz(sent_at, '+01:00', '+00:00')
  

我没有使用命名时区,因为我没有安装mysql时区   表(如文档所述)

之后我尝试使用django.utils.timezone.make_aware使用一个简单的python脚本来识别我的日期时区...没有任何变化,当USE_TZ = True时仍然为零,脚本看起来像:

from django.utils.timezone import is_naive, make_aware, utc
settings.USE_TZ = False
messages = Message.objects.filter(sent_at__year=2011, sent_at__month=1)
for m in messages:
    settings.USE_TZ = True  # Set it to true to avoid errors when datetime becomes timezone aware
    if is_naive(m.sent_at):
        m.sent_at = make_aware(m.sent_at, utc)
        m.save()

相同的结果,按年和月过滤会返回0个元素。

只是为了让你知道,过年仅过滤似乎没问题。

提前致谢


添加模型定义回答评论:

class Message(models.Model):
    subject = models.CharField(_(u"Subject"), max_length=2200)
    body = models.TextField(_(u"Body"))
    sender = models.ForeignKey(
        get_user_model(),
        related_name='sent_messages',
        verbose_name=_(u"Sender"))
    recipient = models.ForeignKey(
        get_user_model(),
        related_name='received_messages',
        null=True, blank=True, verbose_name=_(u"Recipient"))
    parent_msg = models.ForeignKey(
        'self',
        related_name='next_messages',
        null=True, blank=True,
        verbose_name=_(u"Parent message"))
    sent_at = models.DateTimeField(
        _(u"Sent at"), null=True, blank=True, db_index=True)
    read_at = models.DateTimeField(
        _(u"Read at"), null=True, blank=True, db_index=True)
    replied_at = models.DateTimeField(
        _(u"Replied at"), null=True, blank=True, db_index=True)
    sender_status = BitField(
        verbose_name=_(u'Estado sender'),
        flags=FLAGS_MESSAGE,
        db_index=True)
    recipient_status = BitField(
        verbose_name=_(u'Estado recipient'),
        flags=FLAGS_MESSAGE,
        db_index=True)

    class Meta:
        ordering = ['-sent_at']

0 个答案:

没有答案