Самореференциальная таблица SQLAlchemy получает количество внуков - PullRequest
2 голосов
/ 07 декабря 2011

У меня есть модель 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)
        )

... которое работает нормально.То, что я не знаю, как я могу получить количество внуков?Или даже внучат.

Есть идеи?

1 Ответ

2 голосов
/ 07 декабря 2011

Используйте с псевдонимом , чтобы составить более глубокие предложения уровня 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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...