关于mongodb更新操作中safe=True参数的问题
我正在使用 pymongo 这个 Python 模块来操作 MongoDB 数据库。在我的代码中,有一个函数,当调用它时,会更新集合中的记录,代码如下:
for record in coll.find(<some query here>):
#Code here
#...
#...
coll.update({ '_id' : record['_id'] },record)
现在,如果我把代码修改成这样:
for record in coll.find(<some query here>):
try:
#Code here
#...
#...
coll.update({ '_id' : record['_id'] },record,safe=True)
except:
#Handle exception here
这样做是否意味着如果更新失败,就会抛出一个异常,还是说不会抛出异常,更新会跳过这个记录,从而导致问题呢?
请帮帮我,谢谢!
2 个回答
3
try
和 except
这两个东西不会自己制造错误,它们只是用来处理已经出现的错误。
如果 update
在失败时抛出了一个错误,except
就会处理这个错误,然后循环会继续进行(除非你在 except
里使用了 raise
来重新抛出错误)。
如果 update
在失败时没有抛出错误,而是返回了 None
(或者类似的东西),而你又希望它抛出一个错误,你可以使用:
if coll.update(...) is None: # or whatever it returns on failure
raise ValueError # or your custom Exception subclass
注意,你应该总是指定你想要捕捉的错误类型,并且只把你想要捕捉错误的代码行放在 try
里,这样就不会把其他错误隐藏起来:
for record in coll.find(<some query here>):
#Code here
#...
#...
try:
coll.update({ '_id' : record['_id'] },record,safe=True)
except SpecificException:
#Handle exception here
except OtherSpecificException:
#Handle exception here
else:
#extra stuff to do if there was no exception
3
使用 safe=True
这个设置时,如果数据库出现错误,就会抛出一些异常,比如 pymongo.errors.OperationFailure
或它的子类(想了解更多可以查看 pymongo 的文档)。举个例子,我这里制造了一个唯一索引的重复键错误:
>>> db.bar.insert({'a': 1, 'b': 1})
ObjectId('4e4bc586c67f060b25000000')
>>> db.bar.ensure_index('a', unique=True)
u'a_1'
>>> db.bar.insert({'a': 2, 'b': 1}, safe=True)
ObjectId('4e4bc71fc67f060b25000003')
>>> db.bar.update({'a': 2}, {'a': 1}, safe=True)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Library/Python/2.7/site-packages/pymongo/collection.py", line 368, in update
spec, document, safe, kwargs), safe)
File "/Library/Python/2.7/site-packages/pymongo/connection.py", line 770, in _send_message
return self.__check_response_to_last_error(response)
File "/Library/Python/2.7/site-packages/pymongo/connection.py", line 718, in __check_response_to_last_error
raise DuplicateKeyError(error["err"])
pymongo.errors.DuplicateKeyError: E11000 duplicate key error index: test.bar.$a_1 dup key: { : 1 }
(注意,DuplicateKeyError
是 OperationFailure
的一个子类,所以 except OperationFailure: ...
这样的写法会按预期工作。)
除了 update()
方法,save()
、insert()
和 remove()
这些方法也都可以接受 safe
这个参数。你还可以在 Connection
级别设置 safe
,这样就不需要在每次修改数据库时都加上这个参数了。