以下函数排名正确计算数据库中的父项,但我必须像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";
}
}
答案 0 :(得分:2)
将您正在调用方法的实例作为另一个参数传递是多余的,并且您的函数也缺少return语句。更不用说两次执行相同的查询只是为了开始。您可以而且应该只使用self
和self.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。