I quickly made a test subclass of ActiveMapper called LazyMapper that
let's you delay the actual query until the moment you iterate or slice
the results, just like SQLObjects.

i  = Person.select(**you conditions**)
list(i[10:15]) -> issues a select with limit 5 offset 10

To use it:
1. Drop lazymapper.py next to your model.py
2. In model.py add: from lazymapper import LazyMapper
3. Replace the parent in your sqlalchemy objects for LazyMapper:
class Person(ActiveMapper): -> class Person(LazyMapper)

We may need this in the future to complete TG pagination support.
I know this belongs to the SA mailing list (I'll submit this there too),
but I want to see if it works ok on TG apps already using SA.

--
Claudio













--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"TurboGears Trunk" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/turbogears-trunk
-~----------~----~----~----~------~----~------~--~---
from sqlalchemy.ext.activemapper import ActiveMapperMeta, ActiveMapper

def select(cls, *args, **kw):
    return SelectResults(cls, *args, **kw)
select = classmethod(select)

class LazyMapperMeta(ActiveMapperMeta):
    def __init__(cls, name, bases, dict):
        super(LazyMapperMeta, cls).__init__(name, bases, dict)
        mapping = dict.get('mapping', None)
        if mapping:
            cls.select_ = cls.select
            cls.select = select
                
class LazyMapper(ActiveMapper):
    __metaclass__ = LazyMapperMeta
    
class SelectResults(object):
    def __init__(self, mapper, limit=None, offset=0, *args, **kw):
        self.mapper = mapper
        self.limit_ = limit
        self.offset = offset
        self.args = args
        self.kw = kw
    
    def __getitem__(self, index):
        limit = 1
        offset = self.offset + int(index)
        return self.mapper.select_(limit=limit, offset=offset,
                                   *self.args, **self.kw)[0]
    
    def __getslice__(self, start, stop):
        limit = stop - start
        offset = self.offset + start
        if limit <= 0: 
            return []
        return SelectResults(self.mapper, offset=offset, 
                             *self.args, **self.kw).limit(limit)
    
    def __iter__(self):
        items = self.mapper.select_(limit=self.limit_, offset=self.offset, 
                                    *self.args, **self.kw)
        for i in items:
            yield i
            
    def limit(self, limit):
        if self.limit_ and limit > self.limit_: 
            limit = self.limit_
        return SelectResults(self.mapper, limit=limit, offset=self.offset, 
                             *self.args, **self.kw)


Reply via email to