作者:彭润昕_149 | 来源:互联网 | 2023-02-13 21:58
Thepymongodocumentationsays:pymongo文档说:Bydefaultanacknowledgmentisrequestedfromthes
The pymongo documentation says:
pymongo文档说:
By default an acknowledgment is requested from the server that the update was successful, raising OperationFailure
if an error occurred.
默认情况下,来自服务器的确认请求更新是成功的,如果出现错误,将导致操作失败。
I am using Pymongo 2.7.1 with Python 2.7.5. Following operation returns None
, whether the operation is successful or not:
我使用的是Pymongo 2.7.1和Python 2.7.5。以下操作不返回,操作是否成功:
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}})
In second statement I am trying to pull a something which does not exist in friend_list
.
在第二个语句中,我尝试在friend_list中提取一个不存在的东西。
Same happens with remove
also. It's also returns None, be the operation is successful or unsuccessful i.e. if it removed the document or not:
删除也是一样。它也没有返回,操作是成功的或者是不成功的,如果它删除了文档:
user_db.remove({'name': 'john'}
I passed w=1
and I receive following response:
我通过w=1,得到响应:
{u'ok': 1.0, u'err': None, u'connectionId': 12037, u'n': 1, u'updatedExisting': True, u'lastOp': Timestamp(1403099751, 1)}
{u' ': 1.0, u' ':没有,u' connectionid: 12037, u'n': 1, u' updatedexisting ': True, u' lastop ':时间戳(1403099751,1)}
when I manually check the DB, I see it has pulled the name from friend_list
. Now if I run same again i.e. trying to pull a name which does not exist in friend_list
:
当我手动检查DB时,我看到它从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)}
{u' ': 1.0, u'err: None, u' connectionid: 12037, u'n': 1, u' updatedexisting ': True, u' lastop ':时间戳(1403099873,1)}
It is same as earlier.
它和前面一样。
So how do I know whether the update and delete operations are successful or not?
那么我如何知道更新和删除操作是否成功呢?
EDIT: As answers pointed out, I was using connection instead of MongoClient. Now I have updated, remove
is working. However update
is not working properly:
编辑:正如答案所指出的,我使用的是连接而不是MongoClient。现在我已经更新,删除正在工作。但是更新不能正常工作:
>>> 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)}
>>>
The last statement is trying to remove an item from a list, even though the item no longer exists in the list.
最后一个语句试图从列表中删除一个项目,即使该项目不再存在于列表中。
2 个解决方案
1
You're mixing the terms. The section of the documentation you highlighted is referring to the write acknowledgement not number of documents that were updated.
你是混合的。您突出显示的文档部分指的是写入确认,而不是更新的文档数量。
In short, when driver sends a write command to MongoDB and you have the the default write acknowledgment (w=1
) the driver will throw an OperationFailure
error if MongoDB doesn't confirm that the updated completed successful. You can read more details about it on the MongoDB pages.
简而言之,当驱动程序向MongoDB发送一个写命令,并且您有默认的写确认(w=1)时,如果MongoDB不确认更新完成的成功,那么驱动程序将抛出一个OperationFailure错误。您可以在MongoDB页面上阅读更多有关它的详细信息。
Both of your updates were actually successful (MongoDB confirmed that the update was applied). That's why you didn't get an error. Your problem is that your update query didn't actually update any documents.
您的两个更新实际上都是成功的(MongoDB确认了更新的应用)。这就是为什么你没有出错。您的问题是更新查询实际上并没有更新任何文档。
If you do that update in a MongoDB shell v2.6+, where no document are actually modified, you will get a result like this:
如果您在MongoDB shell v2.6+中进行更新,在没有修改文档的情况下,您将得到这样的结果:
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })
And the result for an update that actually changed a document will look like this:
更新后的结果是这样的:
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
Edit:
编辑:
I was using the older version of pymongo (2.6.3) installed on Ubuntu with apt-get
and I was getting the same response for the update query as you were getting.
我使用的是pymongo的旧版本(2.6.3),安装在Ubuntu上的apt-get,我得到的更新查询的响应和你得到的一样。
I removed the python-pymongo package and updated to newest version of pymongo using pip
. I got the following response from update that modified a document:
我删除了python-pymongo包并使用pip更新到最新版本的pymongo。我得到了修改后的更新文件的响应:
{'updatedExisting': True, u'nModified': 1, u'ok': 1, u'n': 1}
I tested this on MongoDB 2.6. using this code.
我在MongoDB 2.6上测试了这个。使用这个代码。
from pymongo import MongoClient
m = MongoClient('localhost', 27017)
db = m.test
print db.test.update({}, {'$pull': {'a' : 1}})
Edit2
Edit2
That's because you're using MongoDB 2.4. If you're using sandbox/free versions on MongoHQ you can't currently change that (link).
这是因为您使用的是MongoDB 2.4。如果你在MongoHQ上使用沙箱/免费版本,你现在不能改变这个(链接)。
MongoDB 2.6 is returning updatedExisting
field in the response to the update command (which is one that's important to you). I suspect that's because the changed write protocol in v 2.6:
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.
写操作的新协议将写操作与写操作集成在一起,消除了对单独的getLastError命令的需要。写方法现在返回写操作的状态,包括错误信息。