Python:MongoDB 按时间戳更新未按预期工作
Python: MongoDB update by timestamp not working as expected
首先,我想说的是,当涉及到 python 时,我完全是个菜鸟,但实际上我目前正在尝试解决 python 脚本中的一个小问题.
所以我使用 mongo 数据库将一些预订数据存储在名为 reservations
.
的 mongo 数据库集合中
采集数据示例:
{
_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
,上面的示例也没有更新是定义。低于 now
(datetime.datetime(2021, 3, 8, 14, 24)
)。其他条目已正确更新...
有人对此有什么建议吗?
日期和时区在 python 和 pymongo 中是一个巨大的陷阱。
在 MongoDB 中使用 date
BSON 类型时,日期始终以 UTC 格式存储。所以你可能认为使用 datetime.datetime.utcnow()
是有意义的 - 但很遗憾不是。
utcnow()
returns 时区原始日期时间。这意味着它将在不同的时区给出不同的结果。我怀疑这将是你的问题。
如果您想赌一把,请确保您的 MongoClient connection 有 tz_aware=True
并使用时区感知日期,例如
import pytz
now = datetime.datetime.now(pytz.utc)
首先,我想说的是,当涉及到 python 时,我完全是个菜鸟,但实际上我目前正在尝试解决 python 脚本中的一个小问题.
所以我使用 mongo 数据库将一些预订数据存储在名为 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
,上面的示例也没有更新是定义。低于 now
(datetime.datetime(2021, 3, 8, 14, 24)
)。其他条目已正确更新...
有人对此有什么建议吗?
日期和时区在 python 和 pymongo 中是一个巨大的陷阱。
在 MongoDB 中使用 date
BSON 类型时,日期始终以 UTC 格式存储。所以你可能认为使用 datetime.datetime.utcnow()
是有意义的 - 但很遗憾不是。
utcnow()
returns 时区原始日期时间。这意味着它将在不同的时区给出不同的结果。我怀疑这将是你的问题。
如果您想赌一把,请确保您的 MongoClient connection 有 tz_aware=True
并使用时区感知日期,例如
import pytz
now = datetime.datetime.now(pytz.utc)