Example #1
0
    def __getitem__(self, path):
        session = DBSession()
        session._autoflush()

        if not hasattr(path, '__iter__'):
            path = (path,)

        if 'children' in self.__dict__:
            # If children are already in memory, don't query the database:
            first, rest = path[0], path[1:]
            try:
                [v] = [child for child in self.children if child.name == path[0]]
            except ValueError:
                raise KeyError(path)
            if rest:
                return v[rest]
            else:
                return v

        # Using the ORM interface here in a loop would join over all
        # polymorphic tables, so we'll use a 'handmade' select instead:
        conditions = [nodes.c.id==self.id]
        alias = nodes
        for name in path:
            alias, old_alias = nodes.alias(), alias
            conditions.append(alias.c.parent_id==old_alias.c.id)
            conditions.append(alias.c.name==unicode(name))
        expr = select([alias.c.id], and_(*conditions))
        row = session.execute(expr).fetchone()
        if row is None:
            raise KeyError(path)
        return session.query(Node).get(row.id)
Example #2
0
    def __getitem__(self, path: Union[str, Iterable[str]]) -> "Node":
        db_session = DBSession()
        db_session._autoflush()

        # if not hasattr(path, '__iter__'):
        if isinstance(path, str):
            path = (path,)
        path = [p for p in path]

        # Optimization: don't query children if self._children already there:
        if "_children" in self.__dict__:
            rest = path[1:]
            try:
                [child] = filter(lambda ch: ch.name == path[0], self._children)
            except ValueError:
                raise KeyError(path)
            if rest:
                return child[rest]
            else:
                return child

        baked_query = bakery(lambda session: session.query(Node))

        if len(path) == 1:
            try:
                baked_query += lambda q: q.filter(
                    Node.name == bindparam("name"),
                    Node.parent_id == bindparam("parent_id"),
                )
                return (
                    baked_query(db_session)
                    .params(name=path[0], parent_id=self.id)
                    .one()
                )
            except NoResultFound:
                raise KeyError(path)

        # We have a path with more than one element, so let's be a
        # little clever about fetching the requested node:
        nodes = Node.__table__
        conditions = [nodes.c.id == self.id]
        alias = nodes
        for name in path:
            alias, old_alias = nodes.alias(), alias
            conditions.append(alias.c.parent_id == old_alias.c.id)
            conditions.append(alias.c.name == name)
        expr = select([alias.c.id], and_(*conditions))
        row = db_session.execute(expr).fetchone()
        if row is None:
            raise KeyError(path)
        return baked_query(db_session).get(row.id)
Example #3
0
    def __getitem__(self, path: Union[str, Iterable[str]]) -> "Node":
        db_session = DBSession()
        db_session._autoflush()

        # if not hasattr(path, '__iter__'):
        if isinstance(path, str):
            path = (path, )
        path = [p for p in path]

        # Optimization: don't query children if self._children already there:
        if "_children" in self.__dict__:
            rest = path[1:]
            try:
                [child] = filter(lambda ch: ch.name == path[0], self._children)
            except ValueError:
                raise KeyError(path)
            if rest:
                return child[rest]
            else:
                return child

        baked_query = bakery(lambda session: session.query(Node))

        if len(path) == 1:
            try:
                baked_query += lambda q: q.filter(
                    Node.name == bindparam("name"),
                    Node.parent_id == bindparam("parent_id"),
                )
                return (baked_query(db_session).params(
                    name=path[0], parent_id=self.id).one())
            except NoResultFound:
                raise KeyError(path)

        # We have a path with more than one element, so let's be a
        # little clever about fetching the requested node:
        nodes = Node.__table__
        conditions = [nodes.c.id == self.id]
        alias = nodes
        for name in path:
            alias, old_alias = nodes.alias(), alias
            conditions.append(alias.c.parent_id == old_alias.c.id)
            conditions.append(alias.c.name == name)
        expr = select([alias.c.id], and_(*conditions))
        row = db_session.execute(expr).fetchone()
        if row is None:
            raise KeyError(path)
        return baked_query(db_session).get(row.id)
Example #4
0
    def __getitem__(self, path):
        session = DBSession()
        session._autoflush()

        if not hasattr(path, '__iter__'):
            path = (path,)
        path = [unicode(p) for p in path]

        # Optimization: don't query children if self._children is already there:
        if '_children' in self.__dict__:
            first, rest = path[0], path[1:]
            try:
                [child] = filter(lambda ch: ch.name == path[0], self._children)
            except ValueError:
                raise KeyError(path)
            if rest:
                return child[rest]
            else:
                return child

        if len(path) == 1:
            try:
                return DBSession.query(Node).filter_by(
                    name=path[0], parent=self).one()
            except NoResultFound:
                raise KeyError(path)

        # We have a path with more than one element, so let's be a
        # little clever about fetching the requested node:
        nodes = Node.__table__
        conditions = [nodes.c.id == self.id]
        alias = nodes
        for name in path:
            alias, old_alias = nodes.alias(), alias
            conditions.append(alias.c.parent_id == old_alias.c.id)
            conditions.append(alias.c.name == name)
        expr = select([alias.c.id], and_(*conditions))
        row = session.execute(expr).fetchone()
        if row is None:
            raise KeyError(path)
        return session.query(Node).get(row.id)
Example #5
0
    def __getitem__(self, path):
        session = DBSession()
        session._autoflush()

        if not hasattr(path, '__iter__'):
            path = (path,)
        path = [unicode(p) for p in path]

        # Optimization: don't query children if self._children already there:
        if '_children' in self.__dict__:
            first, rest = path[0], path[1:]
            try:
                [child] = filter(lambda ch: ch.name == path[0], self._children)
            except ValueError:
                raise KeyError(path)
            if rest:
                return child[rest]
            else:
                return child

        if len(path) == 1:
            try:
                return DBSession.query(Node).filter_by(
                    name=path[0], parent=self).one()
            except NoResultFound:
                raise KeyError(path)

        # We have a path with more than one element, so let's be a
        # little clever about fetching the requested node:
        nodes = Node.__table__
        conditions = [nodes.c.id == self.id]
        alias = nodes
        for name in path:
            alias, old_alias = nodes.alias(), alias
            conditions.append(alias.c.parent_id == old_alias.c.id)
            conditions.append(alias.c.name == name)
        expr = select([alias.c.id], and_(*conditions))
        row = session.execute(expr).fetchone()
        if row is None:
            raise KeyError(path)
        return session.query(Node).get(row.id)