[英]Pymongo UUID search not returning documents that definitely exist
嘗試在 python 中定義一個可以搜索給定 UUID 的函數,如下所示:
def getid(in_id):
return list(CollectionVar.find({"_id":UUID(in_id)}))
並傳入一個 UUID。 我可以從 Studio 3T 獲取我知道存在的 UUID,如下所示:
db.getCollection("CollectionName").find({"_id":UUID("5002aa11-eeb7-4e68-a121-dd51497d2572")})
而上面的查詢正好返回一個文檔。 python 查詢中的相同 UUID 絕對不返回任何內容。 我可以很容易地找到其他(非 UUID)字段上的文檔,例如,以下在之前的同一個文檔上工作正常:
def getname(fn,sn):
return list(CollectionVar.find({"Firstname":re.compile(fn, re.IGNORECASE), "Surname":re.compile(sn, re.IGNORECASE)}))
這似乎是 uuid.UUID 類的問題,而不是 pymongo 的問題? 任何人都可以看到問題嗎?
PyMongo 版本 3.6.1
問題是 PyMongo 默認使用傳統的編碼/解碼 UUID 值的方法。 您可能希望將 PyMongo 客戶端配置為使用更現代、跨語言兼容的“標准”UUID 表示:
client = MongoClient(MONGODB_URI, uuidRepresentation="standard")
現在您應該可以直接使用 Python uuid.UUID
實例進行查詢了:
from uuid import UUID
items = client["item_database"]["items"].find_one({
"uuid": UUID("187382af-1369-43e6-a0ba-d345886c986c")
})
我已經解決了這個問題。 對於遇到此問題的任何其他人,解決方案如下:
from bson.binary import Binary, UUID_SUBTYPE
def getcust(inid):
newuuid=uuid.UUID(inid).bytes
return list(DealershipConsumer.find({"_id": Binary(bytes(bytearray(newuuid)), UUID_SUBTYPE)}))
UUID_SUBTYPE 需要設置為您使用的任何 UUID 子類型 - 在我的情況下它是 4。
您可以在獲取 db 時指定您正在使用的 UUID 類型:
import bson
import pymongo
mongo_client = pymongo.MongoClient(mongo_uri, document_class=dict)
db = mongo_client.get_database(
"my_db_name",
bson.codec_options.CodecOptions(uuid_representation=bson.binary.UUID_SUBTYPE),
)
如果您想在使用 UUID 時閱讀有關 Mongo 最佳實踐的更多信息, 這篇文章可能會有所幫助。
另外,這里是關於codec_options
的文檔
我在bson.binary.UUIDLegacy
類的文檔字符串/評論中從pymongo-2.8.1
中bson.binary.UUIDLegacy
了這個,可能有用
>>> import uuid
>>> from bson.binary import Binary, UUIDLegacy, UUID_SUBTYPE
>>> my_uuid = uuid.uuid4()
>>> coll = db.test
>>> coll.uuid_subtype = UUID_SUBTYPE
>>> coll.insert({'uuid': Binary(my_uuid.bytes, 3)})
ObjectId('...')
>>> coll.find({'uuid': my_uuid}).count()
0
>>> coll.find({'uuid': UUIDLegacy(my_uuid)}).count()
1
>>> coll.find({'uuid': UUIDLegacy(my_uuid)})[0]['uuid']
UUID('...')
>>>
>>> # Convert from subtype 3 to subtype 4
>>> doc = coll.find_one({'uuid': UUIDLegacy(my_uuid)})
>>> coll.save(doc)
ObjectId('...')
>>> coll.find({'uuid': UUIDLegacy(my_uuid)}).count()
0
>>> coll.find({'uuid': {'$in': [UUIDLegacy(my_uuid), my_uuid]}}).count()
1
>>> coll.find_one({'uuid': my_uuid})['uuid']
UUID('...')
您需要使用ObjectId
而不是UUID
。 試試這個,它對我有用:
from bson.objectid import ObjectId
def getid(in_id):
return list(CollectionVar.find({"_id":ObjectId(in_id)}))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.