On Tue, Dec 6, 2011 at 3:33 PM, Daniel Nouri <daniel.no...@gmail.com> wrote:
> Here's a little generalization of that GrandparentTransformer that I
> came up with.
>
>  class ParentalTransformer(Comparator):
>    def __init__(self, expression, level):
>        super(ParentalTransformer, self).__init__(expression)
>        self.level = level
>
>    def operate(self, op, other):
>        def transform(query):
>            cls = Node
>            for i in range(self.level-1):
>                cls, prev_cls = aliased(cls), cls
>                query = query.filter(cls.id==prev_cls.parent_id)
>            return query.filter(op(cls.parent, other))
>        return transform

I experimented a little more with the idea of having parametrized
Transformers.  Here is one that expects a list of names instead of a
level.  At this point, my use is not really related to hybrids
anymore, so I may be using the wrong tools.

    class FollowTransformer(Comparator):
        def __init__(self, expression, names):
            super(FollowTransformer, self).__init__(expression)
            self.names = names

        def operate(self, op, other):
            def transform(query):
                cls = self.__clause_element__()
                for name in self.names[:-1]:
                    cls, prev_cls = aliased(cls), cls
                    query = query.join(cls, getattr(prev_cls, name))
                return query.filter(op(getattr(cls, self.names[-1]), other))
            return transform

You can see how the transform is really similar to what I had before.

On the Node class I can now use it like so:

    class Node(Base):
        __tablename__ = 'node'
        id = Column(Integer, primary_key=True)
        parent_id = Column(Integer, ForeignKey('node.id'))
        parent = relationship("Node", remote_side=id)

        @classmethod
        def follow(cls, *names):
            return FollowTransformer(cls, names)

And it'll allow me to do queries like this:

    session.query(Node).with_transformation(Node.follow('parent',
'parent') == grandparent)

    session.query(Node).with_transformation(Node.follow('parent',
'id') % 2).filter(Node.id > 5)

which I think looks kinda neat.  It reminds of the
DoubleUnderMagicalQuery: http://pastebin.com/31JAxnfZ


-- 
http://danielnouri.org

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalchemy@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.

Reply via email to