How to convert mongo cursor object to a dictionary

7,624 views
Skip to first unread message

Joshua Partogi

unread,
Apr 11, 2010, 11:04:41 PM4/11/10
to mongod...@googlegroups.com
Hi all,

I am currently using mongo with the Python driver. I want to display
the cursor object using a template engine. But the cursor object turns
out to be not-iterable in the template. I have also tried converting
the cursor object with a dict() method, but it didn't quite give the
the expected result.

My question is, how would one actually iterate or pass the mongo
cursor object to a templating engine? I guess it is not really
helpful, especially for web developers, only to iterate the cursor
object in the python script and not be able to pass it to a template.
Is there any other documentation that I can read besides the Mongo
Python API for this?


Kind regards,
Joshua

--
http://twitter.com/projexion

Mcot

unread,
Apr 12, 2010, 1:16:01 AM4/12/10
to mongodb-user
Couldn't you just iterate over it and store it in a dictionary and
then pass that dictionary on?

objects = []
for object in returned_cursor:
objects.append(object)

Joshua Partogi

unread,
Apr 12, 2010, 1:52:24 AM4/12/10
to mongodb-user
Hi Mcot,

I suppose you can, but I just feel that is not really efficient. But
if that is the only way to do it in mongo, then I will go with that.

Kind regards,
Joshua

--
http://twitter.com/projexion

Лоик

unread,
Apr 12, 2010, 3:38:06 AM4/12/10
to mongod...@googlegroups.com
What templating engine do you use?

2010/4/12 Joshua Partogi <joshua....@gmail.com>
--
You received this message because you are subscribed to the Google Groups "mongodb-user" group.
To post to this group, send email to mongod...@googlegroups.com.
To unsubscribe from this group, send email to mongodb-user...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/mongodb-user?hl=en.


Лоик

unread,
Apr 12, 2010, 5:09:07 AM4/12/10
to mongod...@googlegroups.com
I did some test. I've been able to use the cursor inside a mako template. For some reasons, the cursor "deactivate" himself when it's out of the scope. I don't know if there is a way to debug when pymongo does it's queries.

if you use pylons, you should be able to do something like that.

cursor = db.collection.find()
return render('mymako.mako', {'cursor': cursor.clone()})

It would be nice to know if that does make 2 query call to mongo db or we are forced to iterate over the cursor in the controller and in the template (which is absurd).

Michael Dirolf

unread,
Apr 12, 2010, 9:25:52 AM4/12/10
to mongod...@googlegroups.com

The cursor is just an iterable, and it does work in all templating
languages I've tried - if you can send a simple failing test that
would make this much easier to reason about.

As for the example above - the query will only get run when the cursor
is first iterated. If you clone a cursor and then iterate the cloned
cursor and the original cursor separately, two queries will be run -
they don't do any client-side caching or anything like that. Would be
easy to wrap them if that's actually the behavior you want.

Лоик

unread,
Apr 12, 2010, 11:04:47 AM4/12/10
to mongod...@googlegroups.com
Michael, it's true. But I guess there is something wrong with the python driver unless it was designed to act this way.

Actually, it will always work as you said. No need to clone the object.
But there is something wrong with the cursor. I haven't browsed the source yet but I know what was my problem. In my case, after reading this post, I didn't understand why someone would write "the cursor is not iterable" while in the solution of Mcot was to iterate over the cursor and put them in a list. And since templating engine aren't supposed to touch variable and objects, it should just work.

I tested it right away and by coincidence, the cursor in my template iterated over nothing. After reading that line: "the query will only get run when the cursor is first iterated", it reminded me that I was actually iterating over the cursor in my controller, then in my template. The problem, is that you have to manually rewind the cursor with cursor.rewind(). You can rewind it inside or outside the template but since __iter__ return a self reference. That is why it didn't work in my case.

I was first iterating over the cursor in the controller then trying to iterate over it in the template but the cursor was already at the last element.

In my opinion, the cursor should return something like "CursorIterator" that way, we don't have to rewind the cursor manually.

In [36]: for i, value in enumerate(cursor):
   ....:     if i == 0:
   ....:         print i
   ....:         print value
   ....:         break

It will allow some strange behaviour like the one above. If you execute that code over the same cursor. You will have a one different value every time until you reach the end of the cursor. The right behavior for an iterable is to always return the first value in that case.

Loïc

2010/4/12 Michael Dirolf <mi...@10gen.com>

--

Michael Dirolf

unread,
Apr 12, 2010, 11:09:31 AM4/12/10
to mongod...@googlegroups.com
Cursors were designed to act this way - this is how they work in the
rest of the drivers. I don't think it's necessarily bad behavior
either, as it forces you to be explicit if you want to run another
query - otherwise a single cursor would often be performing multiple
queries implicitly.

Лоик

unread,
Apr 12, 2010, 11:19:58 AM4/12/10
to mongod...@googlegroups.com
If you do a rewind() over the cursor it will run an other query?

Michael Dirolf

unread,
Apr 12, 2010, 11:21:19 AM4/12/10
to mongod...@googlegroups.com
Yes.

On Mon, Apr 12, 2010 at 11:19 AM, Лоик <lame...@gmail.com> wrote:
> If you do a rewind() over the cursor it will run an other query?
>

Лоик

unread,
Apr 12, 2010, 12:05:43 PM4/12/10
to mongod...@googlegroups.com
Good to know!

Joshua Partogi

unread,
Apr 12, 2010, 10:49:07 PM4/12/10
to mongodb-user
Hi Michael,

Thank you very much for the insights. It looks like the issue is with
facebook tornado templating engine. I tried with jinja and it works
now.

Kind regards,
Joshua


--
http://twitter.com/projexion


On Apr 12, 11:25 pm, Michael Dirolf <m...@10gen.com> wrote:

Reply all
Reply to author
Forward
0 new messages