如何将CodecOptions应用于mongoengine集合以获取tzinfo?

时间:2016-05-28 21:34:52

标签: python mongodb pymongo mongoengine bson

使用mongoengine Document,当我从mongo加载DateTimeField时,它缺少tzinfo。我们的政策申请要求所有日期时间都为tzinfo

当我保存到mongo时,我知道pymongo在时区中做了正确且可预测的事情;如果它是天真的,则将其存储为UTC时间,如果它具有时区,则将其转换为UTC,然后将其存储为UTC时间。到目前为止一切都很好。

当我加载时,DateTimeField总是给我一个幼稚的datetime。我知道这个datetime是UTC格式的,所以如果我愿意,我可以添加tzinfo,但是我必须在我的应用程序中的几十个地方执行此操作,并且它是'保证未来的时区错误,除非我使用自定义字段类型(参见下面的示例)。

引用:https://api.mongodb.com/python/current/examples/datetimes.html我知道pymongo支持在从数据库到达时将tzinfo放到对象上。我也知道我自己可以这样做,如下面的最小例子所示。 DateTimeTZFieldtzinfo中添加了to_python

from datetime import datetime

from mongoengine import connect, Document, fields

from pytz import timezone

def utcnowTZ():
    return datetime.utcnow().replace(tzinfo=timezone('UTF'))

class DateTimeTZField(fields.DateTimeField):
    """
    This seems like a hack. I would like to use CodecOptions instead
    """
    def to_python(self, value):
        converted = super(DateTimeTZField, self).to_python(value)
        return converted.replace(tzinfo=timezone('UTC'))

class Thing(Document):
    dtTZ = DateTimeTZField(default=utcnowTZ)
    dtXX = fields.DateTimeField(default=utcnowTZ)

connect(host="mongodb://localhost/datetimewithtz")
Thing.objects().delete()

t1 = Thing()
print '%r.dtXX (default): %s' % (t1, t1.dtXX)
print '%r.dtTZ (default): %s' % (t1, t1.dtTZ)
t1.save()
print 'saved %r' % t1.id; print
t1 = Thing.objects(id=t1.id).first()
print 'reloaded %r' % t1.id
print '%r.dtXX (loaded ): %s' % (t1, t1.dtXX)
print '%r.dtTZ (loaded ): %s' % (t1, t1.dtTZ)

在我的应用程序中没有替换DateTimeField,是否有办法使用bson CodecOptions 使全局适用于所有DateTimeFields:从数据库加载时,他们应该附上tzinfo

2 个答案:

答案 0 :(得分:2)

怎么样

connect(...,  tz_aware=True,...)

参数将被转发到MongoClient(..., tz_aware=True, ...)

答案 1 :(得分:1)

我的理解是mongoengine不支持 per-model codec_options。如果有,它们应该是opts字典here的一部分。

但是,当Collection没有任何属性时,PyMongo默认为数据库的codec_options,您可以在向应用程序发出任何请求之前手动调用应用程序中的register_connection来设置它们。 DB。

在上面的示例中,您应该像这样传递codec_options

with_timezone = CodecOptions()
connect(host="mongodb://localhost/datetimewithtz", codec_options=with_timezone)
相关问题