成功的更新/删除操作后,Pymongo返回none

2024-10-05 10:21:10 发布

您现在位置:Python中文网/ 问答频道 /正文

pymongo documentation上写着:

By default an acknowledgment is requested from the server that the update was successful, raising OperationFailure if an error occurred.

我将pymongo2.7.1与python2.7.5一起使用。以下操作返回None,无论操作是否成功:

user_db.update({'email_id': user_email}, {'$pull': {'friend_list': existing_friend}})
user_db.update({'email_id': user_email}, {'$pull': {'friend_list': non_existing_friend}})

在第二个语句中,我试图提取一个在friend_list中不存在的东西。在

remove也会发生这种情况。它还返回None,无论操作成功与否,即如果删除了文档:

^{pr2}$

我通过了w=1并收到以下响应:

{u'ok': 1.0, u'err': None, u'connectionId': 12037, u'n': 1, u'updatedExisting': True, u'lastOp': Timestamp(1403099751, 1)}

当我手动检查数据库时,我看到它从friend_list中提取了名称。现在,如果我再次运行相同的程序,即尝试提取friend_list中不存在的名称:

{u'ok': 1.0, u'err': None, u'connectionId': 12037, u'n': 1, u'updatedExisting': True, u'lastOp': Timestamp(1403099873, 1)}

和以前一样。在

那么我如何知道更新和删除操作是否成功呢?在

编辑:正如答案指出的,我使用的是connection而不是MongoClient。现在我已经更新,remove正在工作。但是update工作不正常:

>>> conn = pymongo.MongoClient(MONGOHQ_URL)
>>> db = conn['test']
>>> test_collection = db.test
>>>
>>> test_collection.insert({'name': 'john'})
ObjectId('53a25612a760360253920619')
>>>  
>>> test_collection.update({'name': 'john'}, {'$addToSet': {'friends': 'merry'}})
{u'ok': 1.0, u'err': None, u'connectionId': 12317, u'n': 1, u'updatedExisting': True, u'lastOp': Timestamp(1403147936, 1)}
>>> 
>>> test_collection.update({'name': 'john'}, {'$pull': {'friends': 'merry'}})
{u'ok': 1.0, u'err': None, u'connectionId': 12317, u'n': 1, u'updatedExisting': True, u'lastOp': Timestamp(1403147959, 1)}
>>> 
>>> test_collection.update({'name': 'john'}, {'$pull': {'friends': 'merry'}})
{u'ok': 1.0, u'err': None, u'connectionId': 12317, u'n': 1, u'updatedExisting': True, u'lastOp': Timestamp(1403147963, 1)}
>>>

最后一条语句试图从列表中删除项,即使该项已不存在于列表中。在


Tags: testfriendnonetruedbupdateoktimestamp
2条回答

我假设您使用的是pymongo.Connection,默认情况下,它会对MongoDB执行未确认的写入操作。因此,Connection不会告诉您更新操作的结果。在

连接已弃用;应改用pymongo.MongoClient。MongoClient有很多优点,包括它在默认情况下进行确认写入。如果使用MongoClient,您将获得有关每个更新的信息:

>>> import pymongo
>>> collection = pymongo.MongoClient().test.collection
>>> collection.insert({'_id': 1, 'array': ['a']})
1
>>> collection.update({'_id': 1}, {'$pull': {'array': 'a'}})
{u'nModified': 1, u'ok': 1, u'n': 1, 'updatedExisting': True, u'electionId': ObjectId('53a1a6bd30492fdb9fb5610a'), u'lastOp': Timestamp(1403111261, 1)}

你把条件混在一起了。您突出显示的文档部分指的是写入确认,而不是更新的文档数。在

简而言之,当驱动程序向MongoDB发送一个write命令并且您拥有默认的写确认(w=1),如果MongoDB不确认更新完成成功,驱动程序将抛出OperationFailure错误。您可以在MongoDB pages上阅读有关它的更多详细信息。在

您的两个更新实际上都是成功的(MongoDB确认更新已应用)。这就是你没有出错的原因。你的问题是你的更新查询实际上没有更新任何文档。在

如果您在MongoDB shell v2.6+中执行此更新,而实际上没有修改任何文档,则会得到如下结果:

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })

实际更改文档的更新结果如下所示:

^{pr2}$

编辑:

我使用的是安装在Ubuntu上的旧版本pymongo(2.6.3)和apt-get并且我得到了与您相同的更新查询响应。在

我删除了python pymongo包,并使用pip更新到pymongo的最新版本。我从修改文档的更新中得到以下响应:

{'updatedExisting': True, u'nModified': 1, u'ok': 1, u'n': 1}

我在MongoDB 2.6上测试过这个。使用此代码。在

from pymongo import MongoClient

m = MongoClient('localhost', 27017)

db = m.test

print db.test.update({}, {'$pull': {'a'  : 1}})

编辑2

那是因为你使用的是MongoDB 2.4。如果您在MongoHQ上使用沙盒/免费版本,那么您目前无法更改(link)。在

MongoDB 2.6在对update命令的响应中返回updatedExisting字段(这对您很重要)。我怀疑这是因为v2.6版本中更改了写入协议:

A new protocol for write operations integrates write concerns with the write operations, eliminating the need for a separate getLastError command. Write methods now return the status of the write operation, including error information.

相关问题 更多 >

    热门问题