Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pymongo forEach formatting

How can I format a forEach function so that it can rest on multiple lines without causing a syntax error? Something like

self.request.db.myCollection.find().forEach( 
    function(u) { 
       u.forSong = self.request.db.song.find_one({}, {'_id': 1})
       self.request.db.save(u)
     })
like image 437
zakdances Avatar asked Mar 26 '26 16:03

zakdances


2 Answers

To pass javascript code in from Python, you need to wrap it in a bson.Code object, since otherwise Python itself (rather than PyMongo) will try to parse it. This gives you:

import bson
self.request.db.myCollection.find().forEach(bson.Code( '''
    function(u) { 
       u.forSong = self.request.db.song.find_one({}, {'_id': 1})
       self.request.db.save(u)
     }'''))

But the fact that you're using self in there makes it look like you want to use Python code there, not javascript code. From the documentation, it looks like the Cursor object returned from find implements Python's Sequence protocol - meaning you ought to just be able to use a regular Python loop instead of forEach (which the docs seem to say that PyMongo doesn't implement anyway):

for u in self.request.db.myCollection.find():
   u.forSong = self.request.db.song.find_one({}, {'_id': 1})
   self.request.db.myCollection.save(u)
like image 127
lvc Avatar answered Mar 28 '26 06:03

lvc


To pass any mongo command without having Python doing anything in the background, you need to use eval. So your example needs to be called this way:

self.request.db.eval('db.myCollection.find().forEach( 
    function(u) { 
       u.forSong = db.song.find_one({}, {"_id": 1});
       self.request.db.save(u);
     })')
like image 37
Cliff Avatar answered Mar 28 '26 06:03

Cliff