Вопрос о safe = True параметре для операции обновления mongodb - PullRequest
4 голосов
/ 17 августа 2011

Я работаю с базой данных mongodb, используя модуль Python Pymongo.В моем коде есть функция, которая при вызове обновляет записи в коллекции следующим образом.

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 голосов
/ 17 августа 2011

Использование safe=True приведет к возникновению исключений (типа pymongo.errors.OperationFailure или подклассов) (см. pymongo docs для получения дополнительной информации), если база данных ответит ошибкой.Например, здесь я вызываю нарушение дубликата ключа для уникального индекса:

>>> 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.Вы также можете установить safe на уровне Connection, чтобы вам не приходилось включать его в каждый вызов, который изменяет базу данных.

3 голосов
/ 17 августа 2011

try и except никогда не вызывают исключение.Они просто обрабатывают выданные исключения.

Если update выдает исключение при сбое, except обработает исключение, тогда цикл продолжится (если вы не используете raise в предложении except).

Если 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

См. try Заявление , Встроенные исключения и Ошибки и исключения .

...