Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PyMongo Cursor Iteration

I'm looking to create and handle a cursor in python the way cursors natively work in mongo. I know the intended way is to do 'result = collection.find()' and do a 'for record in result' but I'm looking to wrap iteration functionality in a class. I'd like to be able to create a new class object and call a function e.g. init_cursor() to make a db connection and do a find returning a cursor. I would then like the have a get_next() function that would move to the next result and set class data members based on the result. Here's the pesudo-code:

class dataIter():
    def __init__(self):
        self.collection = pymongo.Connection().db.collection
        self.cursor = self.collection.find({}) #return all
        self.age = None
        self.gender = None

    def get_next(self):
        if self.cursor.hasNext():
            data = self.cursor.next()
            self.set_data(data)

    def set_data(self, data):
        self.age = data['age']
        self.gender = data['gender']

This way I would be able to simply call:

obj.get_next()
age = obj.age
gender = obj.gender

or some other help functions to pull data out of each document

like image 984
Ghjnut Avatar asked May 03 '12 01:05

Ghjnut


2 Answers

I don't understand how what you are showing is any more convenient that just doing:

col = pymongo.Connection().db.collection
cur = col.find({})

obj = next(cur, None)
if obj:
    age = obj['age']
    gender = obj['gender']

Its not clear how this wrapper is helpful. Also, if what you are really after is an ORM, then don't reinvent the wheel when this exists: http://mongoengine.org/

like image 120
jdi Avatar answered Sep 30 '22 16:09

jdi


You should use the python iterator protocol, you class can look like this

class DataIter:
    def __init__(self):
         self.collection = pymongo.Connection().db.collection
         self.cursor = self.collection.find({}) #return all
         self.age = None
         self.gender = None
    def __iter__(self):
         return self
    def next(self):
        if self.cursor.hasNext():
            data = self.cursor.next()
            self.set_data(data)
            return self
        else:
            raise StopIteration

Then you can iterate like this

for c in DataIter():
    age = c.age
    gender = c.gender
like image 33
Ivo Bosticky Avatar answered Sep 30 '22 16:09

Ivo Bosticky