Использование mongoengine Document
, когда я нахожу DateTimeField
от монго, ему не хватает tzinfo
. Наше приложение по правилам хочет, чтобы все даты имели tzinfo
.Как применить CodecOptions к коллекции mongoengine для получения tzinfo?
Когда я спасу в монго, я знаю, что pymongo делает правильную и предсказуемую вещь по часовой стрелке; если он наивен, он сохраняется как время UTC, если он имеет часовой пояс, он преобразуется в UTC, а затем сохраняется как время UTC. Все хорошо до сих пор.
При загрузке, однако, DateTimeField
всегда дает мне наивный datetime
. Я знаю, что это datetime
в UTC, поэтому я мог бы добавить tzinfo
, если бы захотел, но мне пришлось бы делать это в десятках мест в моем приложении, и это гарантия будущих ошибок в часовом поясе, , если Я использую настраиваемый тип поля (см. пример ниже).
Ссылка: https://api.mongodb.com/python/current/examples/datetimes.html Я знаю, что pymongo поддерживает перенос tzinfo
на объект по мере поступления из базы данных. Я также знаю, что я могу сделать это сам, как показывает следующий минимальный пример. DateTimeTZField
добавляет tzinfo
в 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 прилагаются?
Спасибо за вдумчивый ответ, я вернусь, как только я попробовал это. Я собираюсь создать экземпляр CodecOptions (tz_aware = True), дайте мне знать, если это неправильно. – Cory