On Jun 7, 2011, at 8:57 AM, Filip Zyzniewski - Tefnet wrote:

> # this line:
> print BillGates.subordinates.count()
> # raises:
> # Traceback (most recent call last):
> #   File "count_problem.py", line 60, in <module>
> #     print BillGates.subordinates.count()
> #   File 
> "/home/filip/tefnet/teferp/workspace/tefobjects/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7.egg/sqlalchemy/orm/dynamic.py",
>  line 251, in count
> #     return self._clone(sess).count()
> #   File 
> "/home/filip/tefnet/teferp/workspace/tefobjects/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7.egg/sqlalchemy/orm/query.py",
>  line 2123, in count
> #     return self.from_self(col).scalar()
> #   File 
> "/home/filip/tefnet/teferp/workspace/tefobjects/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7.egg/sqlalchemy/orm/query.py",
>  line 1775, in scalar
> #     ret = self.one()
> #   File 
> "/home/filip/tefnet/teferp/workspace/tefobjects/lib/python2.7/site-packages/SQLAlchemy-0.7.0-py2.7.egg/sqlalchemy/orm/query.py",
>  line 1744, in one
> #     ret = list(self)
> #   File "count_problem.py", line 17, in __iter__
> #     return sqlalchemy.orm.query.Query.__iter__(self.private())
> #   File "count_problem.py", line 20, in private
> #     crit = (self._mapper_zero().class_.isDeleted == False)
> # AttributeError: 'NoneType' object has no attribute 'class_'
> ==============================================================
> 
> As far as I could debug it the problem starts when count() creates a new 
> query with the old one as a subquery (but I could very well be wrong).

Well the recipe actually has a lot of use cases missing, if you said query(A, 
B) for example it only applies the "public" thing to "A".   If it were me I'd 
be calling the private() function explicitly as needed, I think the recipe is 
kind of a hack.  So I can illustrate the extra hooks to get count() to work as 
expected, which is expect None for _mapper_zero(), apply the public() when 
from_self() is called:

class LimitingQuery(Query):

    def get(self, ident):
        # override get() so that the flag is always checked in the 
        # DB as opposed to pulling from the identity map. - this is optional.
        return Query.get(self.populate_existing(), ident)

    def __iter__(self):
        return Query.__iter__(self.private())

    def from_self(self, *ent):
        return Query.from_self(self.private(), *ent)

    def private(self):
        mzero = self._mapper_zero()
        if mzero is not None:
            crit = mzero.class_.public == True

            return self.enable_assertions(False).filter(crit)
        else:
            return self

I'll update the wiki.   

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" 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/sqlalchemy?hl=en.

Reply via email to