How to make customizable "order by" for many-to-one relation to itself in Elixir or SQLAlchemy?

218 Views Asked by At

We have entity Node:

class Node(Entity):
    parent = ManyToOne('Node')
    children = OneToMany('Node')

When we query like this:

nodes = (
    Node.query
    .options(
        eagerload(Node.children),
    )
    .order_by(desc(Node.id))
    .all()
)

fathers = [n for n in nodes if n.parent == None]

we get pretty ordered fathers, in contrast to their children. (fathers[0].children returns unsorted list of nodes)

Almost perfect solution for this problem is to add "order_by" parameter to "children" field in Node. Something like this:

class Node(Entity):
    parent = ManyToOne('Node')
    children = OneToMany('Node', order_by='-id')

And now our children are sorted and everything fine but... What if we want to change criteria for sorting? Sometimes we want sorting by "id", sometimes -- by amount of children or something else. Now our previous solution doesn't look so good.

How can we overcome this?

1

There are 1 best solutions below

1
On BEST ANSWER

Not sure what this Elixir syntaxes are, but here's what I'd do purely using SQLAlchemy. I'd make a function that calls the children not by your default method:

class Node(...):
    def get_children(self, order='new'):
        if order == 'new':
            orderby = Node.created.desc()
        elif order == 'old':
            orderby = Node.created.asc()
        return DBSession.query(Node).filter(Node.parent_id == self.id).order_by(orderby).all()