首页 > 解决方案 > Python:按时间戳更新的 MongoDB 未按预期工作

问题描述

首先,我想说我在 python 方面完全是菜鸟,但实际上我目前正在尝试在 python 脚本中解决一个较小的问题。

所以我使用 mongo db 将一些预订数据存储在一个名为reservations.

采集数据示例:

        {
           _id: ObjectId("5f2820a2f8279f6a284d4f02")
          eventId: "AQMkAGFlMTBmNWMwLTRhNjEtNDFhMS1iOWM3LTc4YjNlYTg5YWIxMQAARgAAA3tu3bjjJ0..."
          startTime: 2020-08-03T12:13:00.000+00:00,
          endTime: 2020-08-03T12:32:00.000+00:00,
          finished: false
        }

现在我正在尝试使用以下代码更新所有过期的事件数据:

        @catch_exceptions()
        def finish_reservations():
            now = datetime.datetime.utcnow().replace(microsecond=0, second=0)
            logging.info("Finishing expired reservations...")
            if db.reservations.count_documents({ "finished": {"$exists": False} }) > 0:
                db.reservations.update_many({ "finished": {"$exists": False} }, {"$set": {"finished": True}})
    
            for reservation in db.reservations.find({"endTime": {"$lt":now}, "finished": {"$eq": False}}):
                db.reservations.update_one(
                    { 'eventId': reservation['eventId'] },
                    { '$set': { 'finished': True } }
                ) 

所以我试图实现的是以下几点:

如果集合中的任何数据尚不存在该字段finished,请将其添加为“true”。之后,检查尚未完成的事件,如果它们的endTime日期和时间时间戳低于日期和时间时间戳,则完成它们now

问题:上面的解决方案实际上并没有更新所有预期的数据条目......即使finished状态是false并且endTime是def,上面的示例也没有更新。低于now( datetime.datetime(2021, 3, 8, 14, 24))。其他条目已正确更新...

有人对此有什么建议吗?

标签: pythonmongodbpymongopython-datetime

解决方案


日期和时区在 python 和 pymongo 中是一个巨大的陷阱。

在 MongoDB 中使用dateBSON 类型时,日期始终以 UTC 存储。所以你可能认为使用 datetime.datetime.utcnow()是有意义的——但遗憾的是不是。

utcnow()返回时区天真的日期时间。这意味着它将在不同的时区给出不同的结果。我怀疑这将是你的问题。

如果您想赌一把,确保您的MongoClient 连接具有tz_aware=True并使用时区感知日期,例如

import pytz
now = datetime.datetime.now(pytz.utc)

推荐阅读