我有一个User模型,每个用户都有另一个用户作为父级。现在,为了获得子节点数(属于给定模型实例的用户),我已经定义了这个属性:
class User( object ):
@property
def childsCount( self ):
return object_session(self).scalar(
select([func.count(User.users_id)]).where(User.parent_id==self.users_id)
)
......哪作得好。我不知道的是如何获得孙子的数量?甚至是爷爷们。
有什么想法吗?
答案 0 :(得分:2)
使用aliased编写更深层WHERE
子句。事实上,你可以做得更通用:
@property
def childrenCount(self):
return self.count_children(0)
@property
def grandchildrenCount(self):
return self.count_children(1)
@property
def grandgrandchildrenCount(self):
return self.count_children(2)
def count_children(self, level=0):
a = [aliased(User) for _ in range(level + 1)]
qry = select([func.count(a[0].users_id)]).where(a[-1].parent_id==self.users_id)
# insert all the intermediate JOINs
for _i in range(level):
qry = qry.where(a[_i].parent_id == a[_i+1].users_id)
return Session.object_session(self).scalar(qry)
虽然它看起来有点神秘,但它真正做的是如下所示(为每个更深层次添加一个alias
和where
子句):
@property
def children1Count(self):
a0 = aliased(User)
qry = select([func.count(a0.users_id)]).where(a0.parent_id==self.users_id)
return Session.object_session(self).scalar(qry)
@property
def children2Count(self):
a0 = aliased(User)
a1 = aliased(User)
qry = select([func.count(a0.users_id)]).where(a0.parent_id==a1.users_id).where(a1.parent_id==self.users_id)
return Session.object_session(self).scalar(qry)
@property
def children3Count(self):
a0 = aliased(User)
a1 = aliased(User)
a2 = aliased(User)
qry = select([func.count(a0.users_id)]).where(a0.parent_id==a1.users_id).where(a1.parent_id==a2.users_id).where(a2.parent_id==self.users_id)
return Session.object_session(self).scalar(qry)
仅限第一级,您可以使用with_parent实际获得更好的查询:
@property
def childrenCount(self):
return Session.object_session(self).query(User).with_parent(self).count()