Search code examples
cachingsqlalchemypyramidchameleontemplate-tal

sql alchemy + pyramid, "request cache"


i'm making a website, using pyramid, sqlalchemy and chameleon... on the view.py i send the sqlalchemy:

@view_config(route_name='entity_subpage')
def entity_subpage_view(request):
    dbsession = DBSession()
    User = dbsession.query(Users).filter_by(id=0).first()
    return render_to_response('page.pt', User=User, request=request)

and chameleon:

<a tal:condition="user.minions.filter_by(dead=0).count() > 1">Prev</a>
<a tal:condition="user.minions.filter_by(dead=0).count() > 1">Next</a>
<repeat tal:omit-tag="" tal:repeat="_page user.minions">
    <condition tal:omit-tag="" tal:condition="not minion.dead"> 
        <li>
             ${minion.name}
        </li>
    </condition>
</repeat>

but the sqlalchemy "user.minions.count()" runs twice, so i added this on models:

class Users(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    name = Column(String(convert_unicode=True))
    minions = dynamic_loader("Minions", backref="User")
    _NumFixedMinions = None

    @property
    def NumAliveMinions(self):
        if not self._NumFixedMinions:
            self._NumFixedMinions = self.minions.filter_by(dead=0).count()
        return self._NumFixedMinions

and started using "NumFixedMinions" instead of the ".count()", but this made the _NumFixedMintions defined until i restarted the server, am i missing something? or is there any way to make a simple "cache" only during the request..

ps:this is not the real code, it's harder to know when somethin will be used twice as the website is modular


Solution

  • Just call count() once in your template:

    <tal:links tal:condition="user.minions.filter_by(dead=0).count() > 1">
        <a>Prev</a>
        <a>Next</a>
    </tal>
    

    For information you want to use perhaps in a request, I'd use a request property; if you set reify to True then it'll only calculated once and only when used:

    def entity_subpage_view(request):
        dbsession = DBSession()
        User = dbsession.query(Users).filter_by(id=0).first()
    
        def dead_minion_count(request):
            return User.minions.filter_by(dead=0).count()
    
        request.set_property(dead_minion_count, 'dead_minion_count', reify=True)
    
        return render_to_response('page.pt', User=User, request=request)
    

    then

    <tal:links tal:condition="request.dead_minion_count > 1">
        <a>Prev</a>
        <a>Next</a>
    </tal>