Mongodb 插入失败后获取插入的ID。\u many()

Mongodb 插入失败后获取插入的ID。\u many(),mongodb,python-3.x,pymongo,Mongodb,Python 3.x,Pymongo,我目前正在尝试编写一个脚本,将文档插入MongoDb并返回每个元素的存储位置。由于insert\u many()非常简单,但是如果在插入时出现错误,则会出现问题 我将无法获取刚刚插入的ID from pymongo import MongoClient client = MongoClient(...) db = client.test r = db.test.insert_many([{'foo': 1}, {'foo': 2}, {'foo': 3}]) r.inserted_ids #

我目前正在尝试编写一个脚本,将文档插入MongoDb并返回每个元素的存储位置。由于
insert\u many()
非常简单,但是如果在插入时出现错误,则会出现问题

我将无法获取刚刚插入的ID

from pymongo import MongoClient

client = MongoClient(...)
db = client.test

r = db.test.insert_many([{'foo': 1}, {'foo': 2}, {'foo': 3}])
r.inserted_ids
#: [ObjectId('56b2a592dfcce9001a6efff8'),
#:  ObjectId('56b2a592dfcce9001a6efff9'),
#:  ObjectId('56b2a592dfcce9001a6efffa')]

list(db.test.find())
#: [{'_id': ObjectId('56b2a592dfcce9001a6efff8'), 'foo': 1},
#:  {'_id': ObjectId('56b2a592dfcce9001a6efff9'), 'foo': 2},
#:  {'_id': ObjectId('56b2a592dfcce9001a6efffa'), 'foo': 3}]

# This is dead stupid, but forcing an error by re-using the ObjectId we just generated
r2 = db.test.insert_many([{'foo': 4}, {'_id': r.inserted_ids[0], 'foo': 6}, {'foo': 7}])
#: ---------------------------------------------------------------------------
#: BulkWriteError                            Traceback (most recent call last)
#: <Cut in the interest of time>
我想要的是能够可靠地计算出按顺序插入的Id。比如:

r2.inserted_ids
#: [ObjectId('56b2a61cdfcce9001a6efffd'),
#:  None, # or maybe even some specific error for this point.
#:  None]
设置
ordered=False
仍然会产生错误,因此
r2
不会被初始化(而且它也不会按照我给出的顺序可靠地返回ID)


这里有选项吗?

捕获抛出的异常。至少根据,返回的错误详细信息包括坏记录。这将使您能够在将记录发送到服务器之前确定成功记录。

。它修改您传递的文档

这意味着您传递的所有文档都保留了
\u id
字段集——成功文档和失败文档

所以你只需要找出哪些是成功的。这可以像@Austin解释的那样完成

比如:

docs = [{'foo': 1}, {'foo': 2}, {'foo': 3}]
try:
    r = db.test.insert_many(docs)
except pymongo.errors.OperationFailure as exc:
    inserted_ids = [ doc['_id'] for doc in docs if not is_failed(doc, exc) ]
else:
    inserted_ids = r.inserted_ids

is_failed(doc,exc)
可以通过在异常详细信息中的失败文档列表中搜索
doc
来实现,如@Austin所述

谢谢你让我注意到这一点,我不知道我能找到一些信息。尽管我仍然觉得我有点迷茫:我如何使用它来找出插入的元素的
ObjectId
?如果您的插入是有序的,那么错误应该指示成功插入的结束。如果您发现坏记录,则该记录之前但不包括该记录的子列表应为成功插入。如果列表是无序的,根据我引用的页面,错误列表包含所有失败,因此您可以从原始列表中减去错误列表,并知道插入的记录。(注意:我没有尝试过,我在猜测。)但是如果
ObjectId
是在服务器端生成的,那么除了知道成功提交了哪些数据之外,还有什么方法可以知道创建的
id
s吗?
docs = [{'foo': 1}, {'foo': 2}, {'foo': 3}]
try:
    r = db.test.insert_many(docs)
except pymongo.errors.OperationFailure as exc:
    inserted_ids = [ doc['_id'] for doc in docs if not is_failed(doc, exc) ]
else:
    inserted_ids = r.inserted_ids