sqlalchemy试图有效地计算数据库中的父母

时间:2017-11-14 20:17:14

标签: python sqlalchemy

以下函数排名正确计算数据库中的父项,但我必须像Group.query。(user_id == 1).rank(0,Group.query。(user_id == 1))一样发送它。看起来效率不高。有没有更好的方法来编写这个函数?

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destinationViewController.
        // Pass the selected object to the new view controller.

        if (segue.identifier == "YourSegueIdentifier") {
            let destinationVC = segue.destination as! YourSegueViewController;

            destinationVC.passedData = "some-data-to-pass";
        }
    }

1 个答案:

答案 0 :(得分:2)

将您正在调用方法的实例作为另一个参数传递是多余的,并且您的函数也缺少return语句。更不用说两次执行相同的查询只是为了开始。您可以而且应该只使用selfself.parent。你的递归函数的基本情况是没有父语句时:

class Group(db.Model):

    def rank(self):
        if not self.parent:
            return 0

        else:
            # Python has no TCO, so no point in trying to
            # use an accumulator
            return 1 + self.parent.rank()

但你是对的,如果你有深层嵌套的结构,这可能不会理想地执行,但是对于几个级别的嵌套,简单的递归可能会击败更复杂的方法。 Group.parent对实例的每次首次访问都会向DB发出新的SELECT语句。您可以对数据执行操作,或者换句话说,在数据库中执行操作。可以使用recursive Common Table Expression

处理树状结构
def rank(self):
    cls = type(self)
    parents = db.session.query(cls.parent_id).\
        filter_by(id=self.id).\
        cte(recursive=True)

    parent_alias = db.aliased(parents)
    group_alias = db.aliased(cls)

    parents = parents.union_all(
        db.session.query(group_alias.parent_id).
            filter(group_alias.id == parent_alias.c.parent_id))

    # Subtract one so that only the parents count
    return db.session.query(db.func.count() - 1).\
        select_from(parents).\
        scalar()

如果您需要计算SQL端一段时间,也可以将其转换为hybrid property