2017-11-14 15 views
0

다음 함수는 데이터베이스의 부모를 올바르게 계산하지만 Group.query (user_id == 1) .rank (0, Group.query. user_id == 1)) 매우 효율적으로 보이지는 않습니다. 이 함수를 작성하는 더 좋은 방법이 있습니까?데이터베이스에서 부모를 효율적으로 계산하려고 시도하는 sqlalchemy

class Group(db.Model): 
    #data 
    id=db.Column(db.Integer, primary_key=True) 
    name=db.Column(db.String(32), nullable=False) 
    #relationships 
    parent_id=db.Column(db.Integer, db.ForeignKey('group.id')) 
    children=db.relationship('Group', backref=db.backref('parent', remote_side=[id])) 

    def rank(self, count, parent): 
     if parent.parent: 
      count=count+1 
      parent.rank(count, parent.parent) 
     else: 
      return count 
+0

다른 말로하면 중첩 수준을 계산하려고합니까? 어떤 DB를 사용하고 있습니까? 또한,'self'를 사용하는 대신'parent' 인수와 같은 인스턴스를'rank()'에 전달하는 이유는 무엇입니까? –

+0

데이터베이스에 sqlite를 사용하고 있습니다. 나는 자기를 사용하여 시도했지만 그것은 단지 0을 계속 유지했다. 나의 생각은 당신이 5 학년이라면 당신의 순위는 5이다. 데이터베이스가 자기 참조 적이기 때문에 나는 새로운 명백한 것이 뿌리로 연결될 때 이것을 바꿀 수 있어야한다. –

답변

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 문을 발행합니다. 작업을 데이터에 적용 할 수 있습니다. 즉 DB에서 수행 할 수 있습니다. 구조와 같은 나무는 recursive Common Table Expression으로 처리 할 수 ​​있습니다 : 당신이 카운트 SQL 팀에게 시간이 필요한 경우도 가능하게하는 hybrid property이을에 돌 수 있었다

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

.

+0

Strong이 파이썬입니다. –