2012-01-09 61 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'}