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.