How to recursively query in django efficiently?

前端 未结 2 1906
旧时难觅i
旧时难觅i 2021-01-02 12:54

I have a model, which looks like:

class StaffMember(models.Model):

    id = models.OneToOneField(to=User, unique=True, primary_key=True, related_name=\'staf         


        
相关标签:
2条回答
  • 2021-01-02 13:11

    I found a solution to the problem. The recursive solution takes the node, goes to it's first child and goes deep down till bottom of the hierarchy. Then comes back up again to the second child (if exists), and then again goes down till the bottom. In short, it explores all the nodes one by one and appends all the members in an array. The solution I came up with, fetches the members layer-wise.

    member = StaffMember.objects.get(id__id=user_id)
    
    new_list = [member]
    
    new_list = get_final_team(new_list)
    
    def get_final_team(qs):
        team = []
        staffmembers = StaffMember.objects.filter(supervisor__in=qs)
    
        team += staffmembers 
        if staffmembers:
            interim_team_qs = get_final_team(staffmembers)
            for qs in interim_team_qs:
                team.append(qs)
        else:
            team = [qs]
    
        return team
    

    The number of db calls this method entails is the number of layers (of hierarchy) that are present beneath the member whose team we want to find out.

    0 讨论(0)
  • 2021-01-02 13:21

    If you're using a database that supports recursive common table expressions (e.g. PostgreSQL), this is precisely the use-case.

    team = StaffMember.objects.raw('''
        WITH RECURSIVE team(id, supervisor) AS (
              SELECT id, supervisor 
              FROM staff_member
              WHERE id = 42
            UNION ALL
              SELECT sm.id, sm.supervisor
              FROM staff_member AS sm, team AS t
              WHERE sm.id = t.supervisor
            )
        SELECT * FROM team
    ''')
    

    References: Raw SQL queries in Django
    Recursive Common Table Expressions in PostgreSQL

    0 讨论(0)
提交回复
热议问题