pymongo 更新不生效

1 投票
2 回答
3309 浏览
提问于 2025-04-17 09:51

我正在尝试使用pymongo更新mongoDB中的一行数据。看起来一切都正常,但实际上并没有更新这行数据!我是不是漏掉了什么(比如说刷新命令)?下面是我的代码片段:

In [161]: articles = connection.journals.articles.find()
In [162]: articles[0]['_id']
Out[162]: ObjectId('4ee61fc0df04c08c5c510b51')

In [163]: articles[0]['newfield'] = 'Test'

In [164]: connection.journals.articles.update({'_id': articles[0]['_id']}, articles[0], safe=True)
Out[164]: 
{u'connectionId': 62,
 u'err': None,
 u'n': 1,
 u'ok': 1.0,
 u'updatedExisting': True}

In [165]: articles = connection.journals.articles.find()

In [166]: articles[0]['_id']
Out[166]: ObjectId('4ee61fc0df04c08c5c510b51')

In [167]: articles[0]['newfield']
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)

script.py in <module>()
----> 1 
      2 
      3 
      4 
      5 

KeyError: 'newfield'

2 个回答

2

这里有一些代码,可能会帮助你理解发生了什么:

# make a connection
>>> import pymongo
>>> articles = pymongo.Connection()['test']['articles']

# insert an article and print out it's contents (make sure it's there)
>>> articles.insert({"title": "tyler's article"})
>>> article = articles.find_one()
>>> article
{u'_id': ObjectId('4f0b353c096f762312000002'), u'title': u"tyler's article"}

# update the title to something new
>>> article['title'] = "test"

# save it
>>> articles.save(article)

# check to see if it changed
>>> print articles.find_one()
{u'_id': ObjectId('4f0b353c096f762312000002'), u'title': u'test'}
1

一个PyMongo Cursor,也就是你调用find()后得到的结果,其实并不是一个真正的列表。它只是通过实现__getitem__这个功能,来模拟列表的访问方式。实际上,每次你用类似列表的方式去取某个元素时,它都会向数据库发起一个新的查询,并设置合适的skip()limit(),以便返回你想要的那个元素。所以,正如你在评论中猜测的那样,直接修改articles[0]的结果是行不通的,但如果你先把articles[0]的结果保存到一个变量里,然后再对这个变量进行修改,并在update()中使用这个变量,那就可以成功了。

你还应该知道,在某些情况下(基本上就是如果修改导致文档的大小超过了旁边可用的空闲空间),MongoDB可能会把这个文档在磁盘或内存中移动。因为你在find()调用中没有使用sort(),所以你得到的结果顺序是不确定的。当文档发生移动时,find()调用的结果顺序可能会改变。

撰写回答