본문 바로가기
Programming/Python_Web

Python - Django 시작하기 4 - oracle DB ORM Join

by Wilkyway 2021. 11. 18.
반응형

Oracle DB의 테이블을 이용해서 Join하는 방법을 알아보겠습니다.

 

1. 모델 정의

1:N관계에서 N쪽 테이블(TempDataroomHstry클래스)에 ForeignKey로 1쪽 테이블명(Temp래스)을 지정해줍니다. 이때, 1쪽 테이블의 참조하려는 필드가 Primary Key로 지정되어있으면 상관없지만, 없을 경우 필드 정의에(ForeignKey 함수 내부에서) to__field='목표필드' 를 지정해줘야 합니다. 그리고, db_column='참조칼럼명' 에서 해당 테이블에서 참조할 실제 칼럼(필드)명을 지정해줘야 합니다.

 

(*) Oracle DB에서만 이런 문제가 발생하는 것인지.. 아직은 잘 모르겠습니다. 이것 때문에 한참을 헤메었네요..^^;; 또한 이번의 경우 Temp의 emp_field와 TempDataroomHstry의 id는 사실 칼럼명은 동일하게 'emp_#'이었습니다. db_column에 넣어주는 값이 현재 테이블의 칼럼명인지, 목표 테이블의 칼럼명인지 좀 헷갈립니다...

<models.py>

from django.db import models


class Temp(models.Model):
    emp_field = models.CharField(db_column='emp_#', primary_key=True, max_length=7)  # Field renamed to remove unsuitable characters. Field renamed because it ended with '_'.
    emp_x = models.CharField(max_length=2, blank=True, null=True)
    kornm_n = models.CharField(max_length=32, blank=True, null=True)    
    res_1 = models.CharField(db_column='res_#1', max_length=12, blank=True, null=True)  # Field renamed to remove unsuitable characters.    
    sex_n = models.CharField(max_length=2, blank=True, null=True)    
    dept_c = models.CharField(max_length=16, blank=True, null=True)
    
    class Meta:
        managed = False
        db_table = 'TEMP'


class TempDataroomHstry(models.Model):
    seq_field = models.IntegerField(db_column='seq_#',primary_key=True)  # Field renamed to remove unsuitable characters. Field renamed because it ended with '_'.
    id = models.ForeignKey(Temp, to_field='emp_field', db_column='emp_#',on_delete=models.CASCADE, null=True, related_name='id')   #, related_name='tempdataroomhstry'
    in_d = models.DateField(blank=True, null=True)


    class Meta:
        managed = False
        db_table = 'TEMP_DATAROOM_HSTRY'

 

2. 데이터 활용하기

Join을 위해서는 "select_related()"나 "prefetch_related()"를 사용하는데, 이번에는 select_related()만 알아보도록 하겠습니다. select_related는 1:1 또는 1:N 의 경우에 사용할 수 있는 함수입니다. (정방향 참조필드). select_related()의 인자로는 해당 Table의 ForeinKey를 넣어줍니다. 아래의 예제에서는 우선 'id'칼럼을 이용하여 join후 모든 데이터를 불러오고 'in_d'를 기준으로 역정렬(desc)을 하여 list를 만들고, 이를 home.html에 넘겨줍니다.

<views.py>

from django.core.paginator import Paginator
from django.http import HttpResponseRedirect
from django.shortcuts import render
from django.urls import reverse

from .models import TempDataroomHstry

#### 초기화면 및 조회함수 ####
def index(request):
    list = {}
    list = TempDataroomHstry.objects.select_related('id').all().order_by('-in_d')

    # HTML에서 인자가 전달될 경우 처리
    q = request.GET.get('q', '')
    if q:
        list = list.filter(id=q)
    # 여기까지
   
    context = {'member_list': list}
    return render(request, 'home.html', context)

A테이블에 B가 조인될 경우 "[A].[조인된A칼럼명].[B칼럼명]"과 같이 사용하면 됩니다. 아래 home.html파일은 실제 Join된 데이터를 불러와 사용하는 예시를 볼 수 있습니다.

<home.html>

....
<tbody>
{% if member_list %}
  {% for member in member_list %}
    <tr>
      <td>{{ member.id.emp_field }}</td>
      <td>{{ member.id.kornm_n }}</td>
      <td>{{ member.id.res_1 }}</td>
      <td>{{ member.id.sex_n }}</td>
      <td>{{ member.id.dept_c }}</td>
      <td>{{ member.in_d }}</td>
    </tr>
  {% endfor %}
{% endif %}
</tbody>

 

~~~끝~~~

반응형

댓글