mongoengine: test1 不是有效的 ObjectId

1 投票
2 回答
5443 浏览
提问于 2025-04-18 18:08

我收到了以下错误信息:

$ python tmp2.py
why??
Traceback (most recent call last):
  File "tmp2.py", line 15, in <module>
test._id = ObjectId(i[0])
  File "/home/mictadlo/.virtualenvs/unisnp/lib/python2.7/site-packages/bson/objectid.py", line 92, in __init__
self.__validate(oid)
  File "/home/mictadlo/.virtualenvs/unisnp/lib/python2.7/site-packages/bson/objectid.py", line 199, in __validate
raise InvalidId("%s is not a valid ObjectId" % oid)
bson.errors.InvalidId: test1 is not a valid ObjectId

这是我用的代码:

from bson.objectid import ObjectId
from mongoengine import *


class Test(Document):
    _id = ObjectIdField(required=True)
    tag = StringField(required=True)


if __name__ == "__main__":
connect('dbtest2')
print "why??"
for i in [('test1', "a"), ('test2', "b"), ('test3', "c")]:
    test = Test()
    test._id = ObjectId(i[0])
    test.char = i[1]
    test.save()

为什么会出现这个问题?难道我不能使用我自己定义的唯一ID吗?

2 个回答

0

有两件事:

ObjectId 需要一个24位的十六进制字符串,你不能用普通字符串来初始化它。比如说,不能用 'test1',而是要用像 '53f6b9bac96be76a920e0799''111111111111111111111111' 这样的字符串。其实你甚至不需要自己去初始化一个 ObjectId,你可以直接这样做:

...
test._id = '53f6b9bac96be76a920e0799'
test.save()
...

我不太清楚你想通过使用 _id 达到什么目的。如果你是想为你的文档生成一个id字段或者“主键”,其实这并不必要,因为MongoDB会自动生成一个。你的代码可以是:

class Test(Document):
    tag = StringField(required=True)

for i in [("a"), ("b"), ("c")]:
    test = Test()
    test.char = i[0]
    test.save()

print(test.id)  # would print something similar to 53f6b9bac96be76a920e0799

如果你坚持要使用一个叫 _id 的字段,你需要知道你的 id 会是一样的,因为在内部,MongoDB把它叫做 _id。如果你还是想用 string1 作为标识符,你应该这样做:

class Test(Document):
    _id = StringField(primary_key=True)
    tag = StringField(required=True)
0

根据文档的说明:http://docs.mongoengine.org/apireference.html#fields,ObjectIdField 是一个用于处理MongoDB中ObjectId的字段包装器。所以它不能接受像字符串 test1 这样的内容作为对象ID。

你可能需要把代码改成这样:

 for i in [(bson.objectid.ObjectId('test1'), "a"), (bson.objectid.ObjectId('test2'), "b"), (bson.objectid.ObjectId('test3'), "c")]:

这样你的代码才能正常工作(假设 test1 等是有效的ID)

撰写回答