python mongodb pymongo

python - Cómo ignorar errores clave duplicados de forma segura mediante insert_many



mongodb pymongo (1)

Necesito ignorar las inserciones duplicadas cuando uso insert_many con pymongo, donde los duplicados se basan en el índice. He visto esta pregunta en stackoverflow, pero no he visto una respuesta útil.

Aquí está mi fragmento de código:

try: results = mongo_connection[db][collection].insert_many(documents, ordered=False, bypass_document_validation=True) except pymongo.errors.BulkWriteError as e: logger.error(e)

Me gustaría que insert_many ignore los duplicados y no arroje una excepción (que llena mis registros de errores). Alternativamente, ¿podría usar un controlador de excepciones por separado para poder ignorar los errores? Echo de menos "w = 0" ...

Gracias


Puede lidiar con esto inspeccionando los errores producidos con BulkWriteError . Esto es realmente un "objeto" que tiene varias propiedades. Las partes interesantes están en details :

import pymongo from bson.json_util import dumps from pymongo import MongoClient client = MongoClient() db = client.test collection = db.duptest docs = [{ ''_id'': 1 }, { ''_id'': 1 },{ ''_id'': 2 }] try: result = collection.insert_many(docs,ordered=False) except pymongo.errors.BulkWriteError as e: print e.details[''writeErrors'']

En una primera ejecución, esto dará la lista de errores en e.details[''writeErrors''] :

[ { ''index'': 1, ''code'': 11000, ''errmsg'': u''E11000 duplicate key error collection: test.duptest index: _id_ dup key: { : 1 }'', ''op'': {''_id'': 1} } ]

En una segunda ejecución, verá tres errores porque todos los elementos existían:

[ { "index": 0, "code": 11000, "errmsg": "E11000 duplicate key error collection: test.duptest index: _id_ dup key: { : 1 }", "op": {"_id": 1} }, { "index": 1, "code": 11000, "errmsg": "E11000 duplicate key error collection: test.duptest index: _id_ dup key: { : 1 }", "op": {"_id": 1} }, { "index": 2, "code": 11000, "errmsg": "E11000 duplicate key error collection: test.duptest index: _id_ dup key: { : 2 }", "op": {"_id": 2} } ]

Entonces, todo lo que necesita hacer es filtrar la matriz para las entradas con "code": 11000 y luego solo "pánico" cuando hay algo más allí

panic = filter(lambda x: x[''code''] != 11000, e.details[''writeErrors'']) if len(panic) > 0: print "really panic"

Eso le brinda un mecanismo para ignorar los errores clave duplicados pero, por supuesto, prestar atención a algo que en realidad es un problema.