Reputation: 8597
I'm trying to update a row in a mongoDB using pymongo. It seems to all work, except that it doesn't actually update the row! Is there something I'm missing (like a flush command?). Code snippet below:
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'
Upvotes: 1
Views: 3329
Reputation: 30136
Here's some code that might help you understand what's going on:
# 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'}
Upvotes: 2
Reputation: 26258
A PyMongo Cursor, the result of a find()
call, isn't actually a list, it just implements __getitem__
to emulate list-like access. In fact, each time you use item-access notation, it performs a new query against the database with an appropriate skip()
and limit()
set in order to return the item you're looking for. So, as you suspected in the comments, modifying the result of articles[0]
won't work, but making a reference to the result of articles[0]
, then modifying and using that in update()
will work.
You should also know that under certain circumstances (basically, if a modification causes the document to grow beyond the free space available "next" to it) the document might be moved on disk/in memory by MongoDB. Since you are not using sort()
in your find()
call, you are getting results in an undefined order. When documents move, the order of results in the find()
call may change if documents have moved.
Upvotes: 1