如何在 Elixir 或 SQLAlchemy 中为与其自身的多对一关系创建可自定义的“排序依据”?

Posted

技术标签:

【中文标题】如何在 Elixir 或 SQLAlchemy 中为与其自身的多对一关系创建可自定义的“排序依据”?【英文标题】:How to make customizable "order by" for many-to-one relation to itself in Elixir or SQLAlchemy? 【发布时间】:2012-02-01 22:00:41 【问题描述】:

我们有实体节点:

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

当我们这样查询时:

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

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

与他们的孩子相比,我们得到了非常有条理的父亲。 (fathers[0].children 返回未排序的节点列表)

这个问题几乎完美的解决方案是在Node.js中的“children”字段中添加“order_by”参数。像这样的:

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

现在我们的孩子已经分类,一切都很好,但是...... 如果我们想改变排序标准怎么办?有时我们想要按“id”排序,有时——按孩子的数量或其他东西。现在我们之前的解决方案看起来不太好。

我们如何克服这个问题?

【问题讨论】:

【参考方案1】:

不确定 Elixir 的语法是什么,但这是我纯粹使用 SQLAlchemy 所做的。我会创建一个不通过默认方法调用孩子的函数:

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()

【讨论】:

谢谢。我也没有找到更好的东西。

以上是关于如何在 Elixir 或 SQLAlchemy 中为与其自身的多对一关系创建可自定义的“排序依据”?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 erlang 或 elixir 中接收可能值列表

如何安排代码在 Elixir 或 Phoenix 框架中每隔几个小时运行一次?

如何通过在 Elixir 中调用进程来捕获或挽救被调用进程的崩溃错误

在 SQLAlchemy 中“扩展”自反多对多关系

如何在Elixir或Erlang中在运行时动态创建和加载模块?

如何在 Elixir 中生成随机数?