2011-12-07 6 views
2

私はユーザーモデルを持っており、各ユーザーは親として別のユーザーを持っています。SQLAlchemy自己参照表は孫の数を取得

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

... [OK]を動作します。今、私は、このプロパティを定義している(与えられたモデルのインスタンスに属するユーザー)子どもの数を取得します。私が知らないことは、どうやって孫の数を得るのですか?それとも、大草原でさえ。

アイデア?

答えて

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) 

を、それはやや不可解に見えますが、それは本当に、次のようにexpanedされないものを(1 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() 
+0

私はまだsqlalchemyとpythonには新しかったですが、これはすでに中国語です。それを消化しようとします。 Btw、それは動作します!ありがとう。 –

+1

@Romeo:理解を容易にするためにコードをいくらか解読しました – van