복붙노트

[PYTHON] django ORM을 사용하여 외래 키 필드에서 두 테이블을 어떻게 조인합니까?

PYTHON

django ORM을 사용하여 외래 키 필드에서 두 테이블을 어떻게 조인합니까?

다음 모델이 있다고 가정 해 보겠습니다.

class Position(models.Model):
    name = models.CharField()

class PositionStats(models.Model):
    position = models.ForeignKey(Position)
    averageYards = models.CharField()
    averageCatches = models.CharField()

class PlayerStats(models.Model):
    player = models.ForeignKey(Player)
    averageYards = models.CharField()
    averageCatches = models.CharField()

class Player(models.Model):
    name = models.CharField()
    position = models.ForeignKey(Position)

django의 ORM을 사용하여 동등한 SQL 쿼리를 수행하고자합니다.

SELECT *

FROM PlayerStats

JOIN Player ON player

JOIN PositionStats ON PositionStats.position = Player.position

어떻게 장고의 ORM으로 그걸 할 수 있을까요? 쿼리가 정확하지는 않지만 플레이어의 위치를 ​​기반으로 PositionStats에 PlayerStats가 조인 된 Django의 ORM을 사용하는 단일 쿼리를 원한다는 아이디어가 있습니다.

해결법

  1. ==============================

    1.하나의 쿼리가 아니지만 꽤 효율적입니다. 관련된 각 테이블에 대해 하나의 쿼리를 수행하고이를 파이썬으로 조인합니다. prefetch_related에 대한 자세한 내용은 https://docs.djangoproject.com/en/dev/ref/models/querysets/#prefetch-related를 참조하십시오.

    하나의 쿼리가 아니지만 꽤 효율적입니다. 관련된 각 테이블에 대해 하나의 쿼리를 수행하고이를 파이썬으로 조인합니다. prefetch_related에 대한 자세한 내용은 https://docs.djangoproject.com/en/dev/ref/models/querysets/#prefetch-related를 참조하십시오.

    Player.objects.filter(name="Bob").prefetch_related(
            'position__positionstats_set', 'playerstats_set')
    
  2. ==============================

    2.나는 잠시 동안 지금 장고와 함께 일해 왔고 테이블 조인을 계산하는 데 꽤 힘든 시간을 보냈지 만 마침내 이해할 수 있다고 생각하며 다른 사람들에게 전달하여 내가 갖고있는 좌절감을 피할 수있게하려고한다. 그것으로.

    나는 잠시 동안 지금 장고와 함께 일해 왔고 테이블 조인을 계산하는 데 꽤 힘든 시간을 보냈지 만 마침내 이해할 수 있다고 생각하며 다른 사람들에게 전달하여 내가 갖고있는 좌절감을 피할 수있게하려고한다. 그것으로.

    다음 model.py를 고려하십시오.

    class EventsMeetinglocation(models.Model):
        id = models.IntegerField(primary_key=True)
        name = models.CharField(max_length=100)
        address = models.CharField(max_length=200)
    
        class Meta:
            managed = True
            db_table = 'events_meetinglocation'
    
    
    class EventsBoardmeeting(models.Model):
        id = models.IntegerField(primary_key=True)
        date = models.DateTimeField()
        agenda_id = models.IntegerField(blank=True, null=True)
        location_id = models.ForeignKey(EventsMeetinglocation)
        minutes_id = models.IntegerField(blank=True, null=True)
    
        class Meta:
           managed = True
           db_table = 'events_boardmeeting'
    

    여기서 EventsBoardmeeting의 location_id가 EventsMeetinglocation의 ID에 대한 외래 키임을 알 수 있습니다. 즉, EventsBoardmeeting을 통해 EventsMeetinglocation의 정보를 쿼리 할 수 ​​있어야합니다.

    이제 다음과 같은 views.py를 고려하십시오.

    def meetings(request):
        meetingData = EventsBoardmeeting.objects.all()
        return render(request, 'board/meetings.html', {'data': meetingData })
    

    전에 다른 글에서 여러 번 언급했듯이 django는 자동으로 조인을 처리합니다. 우리가 EventsBoardmeeting에서 모든 것을 쿼리 할 때 우리는 또한 외래 키에 의해 관련된 정보를 얻습니다. 그러나 우리가 html로 이것을 접근하는 방법은 조금 다릅니다. 외부 키로 사용 된 변수를 통해 해당 조인과 관련된 정보에 액세스해야합니다. 예 :

    {% for x in data %}
       {{ x.location_id.name }}
    {% endfor %}
    

    위 표는 외부 키 조인의 결과 인 테이블의 모든 이름을 참조합니다. x는 기본적으로 EventsBoardmeeting 테이블이므로 x.location_id에 액세스 할 때 우리는 EventsMeetinglocation의 정보에 액세스 할 수있는 외래 키에 액세스하고 있습니다.

  3. ==============================

    3.select_related () 및 prefetch_related ()가 솔루션입니다. 그들은 거의 같은 방식으로 작동하지만 약간의 차이가 있습니다.

    select_related () 및 prefetch_related ()가 솔루션입니다. 그들은 거의 같은 방식으로 작동하지만 약간의 차이가 있습니다.

    select_related ()는 SQL 조인을 작성하고 SELECT 문에 관련 오브젝트의 필드를 포함시켜 작동합니다. 이러한 이유로 select_related는 동일한 데이터베이스 쿼리에서 관련 객체를 가져옵니다. 그러나 일대일 또는 일대 다 관계에서만 작동합니다. 아래의 예는

    entry = Entry.objects.select_related('blog').get(id=5)
    or
    entries = Entry.objects.filter(foo='bar').select_related('blog')
    

    한편, prefetch_related ()는 각 관계에 대해 별도의 조회를 수행하고 Python에서 '가입'을 수행합니다. 이렇게하면 select_related를 사용하여 수행 할 수없는 다 대다 및 다 대일 오브젝트를 프리 페! 할 수 있습니다. 따라서 prefetch_related는 각 관계에 대해 하나의 쿼리 만 실행합니다. 보기는 아래에 주어진다.

    Pizza.objects.all().prefetch_related('toppings')
    
  4. ==============================

    4.django.db 가져 오기 연결에서보기에는 다음 문이 포함됩니다.

    django.db 가져 오기 연결에서보기에는 다음 문이 포함됩니다.

    cursor = connection.cursor()
    cursor.execute("select * From Postion ON Position.name = Player.position JOIN
    PlayerStats ON Player.name = 
    PlayerStats.player JOIN PositionStats ON Position.name = PositionStats.player")
    solution = cursor.fetchall()
    
  5. from https://stackoverflow.com/questions/13092268/how-do-you-join-two-tables-on-a-foreign-key-field-using-django-orm by cc-by-sa and MIT license