簡體   English   中英

PyMongo:無法更新超過 7 天的條目。 需要處理 ISODate

[英]PyMongo: Unable to update entries older than 7 days. Need to handle ISODate

我正在嘗試創建一個腳本,該腳本將更新 Mongo 中具有待處理狀態的條目,這些條目是在 7 天前創建的。 但是,我遇到的問題似乎源於創建日期的存儲方式。

我在 mongodb 中運行以下命令:

db.jobs.find( {"$and":[{"status": "PENDING"},{"createdOn":{"$lt":ISODate('2020-11-30T00:00:00.00000')}}]})

ISODate 是 7 天前的位置。 我得到在那之前創建的條目(注意:我不確定為什么 $lt 對此有效,但是當我執行 $gt 時,我沒有得到任何結果)。 返回的條目中的 createdOn 字段如下所示:

"createdOn" : ISODate("2020-11-20T18:50:40.062Z")

當我在 python 中運行類似批次的代碼時:

from pymongo import MongoClient
import pymongo
from datetime import datetime, timedelta

newDate = datetime.utcnow() - timedelta(days=7)

pendingJobs = list(db.jobs.find( {"$and":[{"state": "PENDING"},{"createdOn":{"$lt":newDate}}]}))
print(pendingJobs)

日期以下列格式返回:

'createdOn': datetime.datetime(2020, 11, 20, 18, 50, 40, 62000)

這似乎阻止我使用 pymongo 更新狀態字段:

db.jobs.update( {"$and":[{"state": "PENDING"},{"createdOn":{"$lt":newDate}}]}, { "$set": {"status":"FAILED"} })

由於 pymongo 使用 datetime 運行,而 Mongo 使用 ISODate 運行。 我該如何解釋呢? 我已經嘗試了以下沒有效果:

  • 將 newDate 格式化為 ISODate
isoDate = newDate.isoformat()

db.jobs.update( {"$and":[{"state": "PENDING"},{"createdOn":{"$lt":isoDate}}]}, { "$set": {"status":"FAILED"} })
  • 嘗試將“ISODate”合並到字符串本身:
db.jobs.update( {"$and":[{"state": "PENDING"},{"createdOn":{"$lt":"ISODate('"+isoDate+"')"}}]}, { "$set": {"status":"FAILED"} })

pymongo 驅動程序將 map 和 python datetime.datetime轉換為您在 shell 中看到的 BSON date作為ISODate 所以你的第一種方法很好 - 不需要對日期做任何花哨的事情。

值得注意的是 MongoDB 過濾器默認為AND ed,因此您可以簡單地查詢:

db.jobs.find({"state": "PENDING", "createdOn": {"$lt": newDate}})

我懷疑您的根本原因是您正在查詢state但正在更新status

此代碼示例應該可以工作:

from pymongo import MongoClient
from datetime import datetime, timedelta

db = MongoClient()['mydatabase']

# Set up some sample data

for days in range(8):
    db.jobs.insert_one({'state': 'PENDING', 'createdOn': datetime.utcnow() - timedelta(days=days)})

newDate = datetime.utcnow() - timedelta(days=7)

db.jobs.update_many({"state": "PENDING", "createdOn": {"$lt": newDate}}, {'$set': {'state': 'FAILED'}})

pendingJobs = list(db.jobs.find({'state': 'FAILED'}))
print(pendingJobs)

印刷:

[{'_id': ObjectId('5fce82c2916f9131fec02966'), 'state': 'FAILED', 'createdOn': datetime.datetime(2020, 11, 30, 19, 30, 10, 393000)}]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM