ORM(Object Relational Mapping)
관계형 데이터베이스를 사용할 격우에는 데이터베이스의 데이터를 조회하거나 저장하기 위해 SQL을 사용해야 했다. 그런데 개발자마다 비슷한데 약간 다른? 다양한 쿼리문이 만들어지고, 또 잘못 작성된 SQL은 시스템의 퍼포먼스를 떨어뜨릴 수 있다. 또한 흔치는 않지만 데이터베이스 서버를 Oracle에서 MariaDB로 변경하게 되면 프로그램에서 사용한 쿼리문을 모두 해당 데이터베이스의 규칙에 맞게 수정해야 하는 문제가 생긴다. 이때 Django가 제공하는 ORM을 사용하면 데이터베이스의 테이블을 모델화하여 사용하기 때문에 데이터베이스 서버를 변경해도 파이썬 소스 코드에는 변함이 없다.
이렇듯 Django ORM을 사용하면 개발자 별로 약간씩 다른 SQL을 작성하여 혼란을 주는 문제에서 자유로울 수 있으며, 데이터베이스 서버가 변경되더라도 자유롭게 모델을 사용하기 때문에 프로그램을 수정할 필요가 없다.
정리하면 ORM을 이용하면 데이터베이스 종류에 상관 없이 일관된 코드를 유지할 수 있어서 프로그램을 유지·보수하기가 편리하며, 실행시 ORM 도구가 SQL 쿼리를 자동으로 생성해 주므로 개발자나 RDBMS가 달라도 통일된 쿼리를 작성할 수 있고 당연히 오류 발생률도 줄일 수 있다.
--- Django ORM으로 SELECT 연습 ---
Django Model API에는 기본적으로 제공하는 여러 쿼리 메서드들이 있는데, 대표적인 몇 가지만 살펴보자.
(TableName 모델 클래스를 기준으로 설명)
1) all() : 테이블 자료를 모두 가져오기 위해서는 TableName.objects.all() 과 같이 all()을 사용한다.
다음은 TableName 테이블의 모든 데이타의 id와 name 컬럼을 출력하는 예이다.
for f in TableName.objects.all():
s += str(f.id) + ' : ' + f.name + '\n'
2) get() : 하나의 Row만을 가져오기 위해서는 get()을 사용한다. 아래는 Primary Key (일반적으로 id 컬럼)가 1인 row를 가져온다.
row = TableName.objects.get(pk=1)
print(row.name)
3) filter() : 특정 조건에 맞는 레코드를 가져오기 위해서는 filter()를 사용한다. 아래는 name 필드가 Kim 인 데이타만 가져온다.
rows = TableName.objects.filter(name='Kim')
4) exclude() : 특정 조건을 제외한 나머지 Row들을 가져오기 위해서는 exclude() 를 사용한다.
아래의 경우에는 name 필드가 '홍길동'이 아닌 데이타만 가져온다.
rows = TableName.objects.exclude(name='홍길동')
4) count() : 데이타의 갯수(row 수)를 세기 위해 count() 를 사용한다.
n = TableName.objects.count()
5) order_by() : 데이타를 키에 따라 정렬하기 위해 order_by() 를 사용한다.
order_by() 안에는 정렬 키를 나열할 수 있는데, 키 앞에 -(하이픈)가 붙으면 내림차순이다.
아래는 id를 기준으로 오름차순, createDate로 내림차순으로 정렬하게 된다.
rows = TableName.objects.order_by('id', '-name')
6) distinct() : 중복된 값은 하나로만 표시하기 위해 distinct() 를 사용한다.
아래는 name필드가 중복되는 경우 한번만 표시하게 된다.
rows = TableName.objects.distinct('name')
7) first() : 데이타들 중 처음에 있는 레코드를 리턴한다.
rows = TableName.objects.order_by('name').first()
8) last() : 데이타들 중 마지막에 있는 레코드를 리턴한다.
rows = TableName.objects.order_by('name').last()
9) method chain : 다음으로 여러 메서드를 체인처럼 연결하여 사용할 수 있다.
즉, 여러 체인으로 연결되어 리턴된 쿼리가 해석되어 DB에 실제 하나의 쿼리를 보내게 된다.
row = TableName.objects.filter(name='Kim').order_by('-id').first()
참고 : UPDATE
데이타를 수정하기 위해서는 먼저 수정할 Row 객체를 얻은 후 변경할 필드들을 수정한다.
이어 마지막에 save() 를 호출되면, SQL의 UPDATE이 실행되어 테이블에 데이타가 갱신된다.
아래는 id가 1인 TableName 객체에 이름을 변경하는 코드이다.
fb = TableName.objects.get(pk=1)
fb.name = 'Park'
fb.save()
참고 : DELETE
데이타를 삭제하기 위해서는 먼저 삭제할 Row 객체를 얻은 후 delete() 를 호출하면 된다.
아래는 id가 2인 TableName 객체를 삭제하는 코드이다.
fb = TableName.objects.get(pk=2)
fb.delete()
QuerySet 참고 사이트
https://lqez.github.io/blog/django-queryset-basic.html
https://docs.djangoproject.com/en/4.0/topics/db/queries/
https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=dudwo567890&logNo=220924729927
https://docs.djangoproject.com/en/4.0/topics/db/queries/
Django ORM Cookbook https://django-orm-cookbook-ko.readthedocs.io/en/latest/index.html
join 관련 https://brownbears.tistory.com/101