2012-01-09 110 views
1

我试图用pymongo更新mongoDB中的一行。似乎所有的工作,除了它并没有实际更新行!是否有我失踪的东西(如flush命令?)。下面的代码片段:pymongo更新不起作用

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' 
+0

好好像更新'的文章[0]'不改变对象!通过'article = articles [0]'制作副本第一个作品... – tdc 2012-01-09 14:46:35

+1

我认为'connection.journals.articles.save(articles [0])'是为此做出的。 – reclosedev 2012-01-09 15:12:59

回答

1

一个PyMongo Cursor,一个find()调用的结果,其实不是一个列表,它只是实现__getitem__效仿列表类似的访问。实际上,每次您使用物品访问表示法时,它都会对数据库执行新的查询,并设置相应的skip()limit()以返回您正在查找的物品。因此,如您在评论中所怀疑的那样,修改articles[0]的结果将不起作用,但请参考articles[0]的结果,然后修改并使用update()中的结果。

您应该也知道,在某些情况下(基本上,如果修改导致文档增长超出“接下来”的可用空间),文档可能会被MongoDB在磁盘上/内存中移动。由于您在find()调用中没有使用sort(),因此您将以未定义的顺序获得结果。文档移动时,如果文档已移动,find()调用中的结果顺序可能会更改。

+0

丁!这很有道理......谢谢! – tdc 2012-01-10 09:41:27

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'}