한 걸음씩

[Django] ORM 본문

Django

[Django] ORM

winter17 2023. 3. 28. 11:32

1. 개요

 ► ORM

  • Object-Relational-Mapping
  • 객체 지향 프로그래밍 언어를 사용하여 호환되지 않는 유형의 시스템 간에 데이터를 변환하는 프로그래밍 기술

2. QuerySet API

 ► QuerySet API

  • ORM에서 데이터를 검색, 필터링, 정렬 및 그룹화 하는데 사용하는 도구
  • API를 사용하여 SQl이 아닌 Python 코드로 데이터를 처리

 

 

 Article.objects.all() 형태로 요청을 보내면 

 SQL은 SELECT * FROM ~ 과 같은 형태로 받고

 DB로부터 응답을 받음

 

 

► Query

  • 데이터베이스에 특정한 데이터를 보여 달라는 요청
  • "쿼리문을 작성한다"
    • 원하는 데이터를 얻기 위해 데이터베이스에 요청을 보낼 코드를 작성한다
  • 이때, 파이썬으로 작성한 코드가 ORM의 의해 SQL로 변환되어 데이터베이스에 전달되며, 데이터베이스의 응답 데이터를 ORM이 QuerySet이라는 자료 형태로 변환하여 우리에게 전달

 

► QuerySet

  • 데이터베이스에게서 전달 받은 객체 목록(데이터 모음)
    • 순회가 가능한 데이터로써 1개 이상의 데이터를 불러와 사용할 수 있음
  • Django ORM을 통해 만들어진 자료형
  • 단, 데이터베이스가 단일한 객체를 반환할 때는 QuerySet이 아닌 모델(Class)의 인스턴스로 반환됨

 


3. ORM CREATE

 ► QuerySet API 실습 사전 준비

 

 ► Django shell

  • django 환경 안에서 실행되는 python shell
  • 입력하는 QuerySet API 구문이 django 프로젝트에 영향을 미침

 

 ► 데이터 객체를 만드는(생성하는) 3가지 방법

  • class에 대한 이해 반드시 필요! (class, instance ...)
  • save() : 객체를 데이터베이스에 저장하는 메서드

 ► 첫번째 방법

# 터미널에 입력
python manage.py shell_plus

# 특정 테이블에 새로운 행을 추가하여 데이터 추가
articles = Articles() # Articles(class)로부터 articles(instance)
articles
>> <Articles: Articles object (None)>

articles.title = 'first'

articles.content = 'django!'

# save를 하지 않으면 아직 DB에 값이 저장되지 않음
articles
>> <Articles: Articles object (None)>

Articles.objects.all()
>> <QuerySet []>

# save를 하고 확인하면 저장된 것을 확인할 수 있다
# save 메서드를 호출해야 비로소 DB에 데이터가 저장(레코드 생성)
articles.save()

articles
>> <Articles: Articles object (1)>

articles.id
>> 1

articles.pk # pk가 id보다 더 직관적이기 때문에 pk로 사용하는 것을 권장!!
>> 1

Articles.objects.all()
>> <QuerySet [<Articles: Articles object (1)>]> # 순회가능

# 인스턴스인 articles을 활용하여 변수에 접근해보자(데이터 저장된 것을 확인)
articles.title
>> 'first'

articles.content
>> 'django!'

articles.created_at
>> datetime.datetime(2023, 3, 28, 1, 35, 35, 866667, tzinfo=<UTC>)

 

 두번째 방법

article = Articles(title='second', content='django!')

# 아직 저장 되어있지 않음
article
>> <Articles: Articles object (None)>

# save를 호출해야 저장됨
article.save()

article
>> <Articles: Articles object (2)>

Articles.objects.all()
>> <QuerySet [<Articles: Articles object (1)>, <Articles: Articles object (2)>]>

# 값 확인
article.pk
>> 2

article.title
>> 'second'

article.content
>> 'django!'

 

 ► 세번째 방법

# 위 2가지 방식과는 다르게 바로 생성된 데이터가 반환된다
# 아래 방식은 save 기능이 내장되어있어서 따로 save하지 않아도 됨
Articles.objects.create(title='third', content='django!')
>> <Articles: Articles object (3)>
# QuerySet API 중 create() 메서드 활용

# 총 3개의 글이 있다는 것을 확인할 수 있음
Articles.objects.all()
>> <QuerySet [<Articles: Articles object (1)>, 
			  <Articles: Articles object (2)>, 
              <Articles: Articles object (3)>]
   >

 

최종 결과

⎣ 위의 3가지 방법을 실행하면 db.sqlite3의 articles_articles에 생성되어있는 것을 확인할 수 있음

 

 

 ► 주의사항

# 4번째 게시글 작성
article = Articles(title='4444', content='django!')

# 저장을 하지 않은채로 pk를 불러내면 아무것도 보여주지 않음
article.pk
>>

# 저장 후 pk 호출해야 함
article.save()

4. ORM READ

 ►  전체 데이터 조회

  • all() 메서드
Articles.objects.all()
>> <QuerySet [<Articles: Articles object (1)>, <Articles: Articles object (2)>, <Articles: Articles object (3)>]>

 

 단일 데이터 조회

  • get() 메서드
    • 객체를 찾을 수 없으면 DoesNotExist 예외를 발생시키고, 둘 이상의 객체를 찾으면 MultipleObjectsReturned 예외를 발생시킴
    • 위와 같은 특징을 가지고 있기 때문에 primary key와 같이 고유성(uniqueness)을 보장하는 조회에서 사용해야 함
Articles.objects.get(pk=1)
>> <Articles: Articles object (1)>

Articles.objects.get(pk=100)
>> DoesNotExist

Articles.objects.get(content='django!')
>> MultipleObjectsReturned

 

 특정 조건 데이터 조회

  • filter() 메서드
Articles.objects.filter(content='django!')
>> <QuerySet [<Articles: Articles object (1)>, <Articles: Articles object (2)>, <Articles: Articles object (3)>]>

Articles.objects.filter(title='first')
>> <QuerySet [<Articles: Articles object (1)>]>

Articles.objects.filter(title='ssafy')
>> <QuerySet []>

4. 참고

 ► QuerySet API 관련 문서

 

 ►  Field lookups

# Field lookups 예시

# 'content 칼럼에 'dj'가 포함된 모든 데이터 조회'
Articles.objects.filter(content__contains='dj')

 

 ►   ORM, QuerySet API 사용하는 이유

  • 데이터베이스 쿼리를 추상화하여 django 개발자가 데이터베이스와 직접 상호작용하지 않아도 되도록 함
  • 데이터베이스와의 결합도를 낮추고 개발자가 더욱 직관적이고 생산적으로 개발할 수 있도록 도움
  • 복잡한 db라면 sql사용해야 함

 

 ►  SQL 미리보기

  • sql로 번역이 어떻게 되는지 궁금하면 print와 query를 통해 알 수 있다
Articles.objects.all()
>> <QuerySet [<Articles: Articles object (1)>, <Articles: Articles object (2)>, <Articles: Articles object (3)>]>

# sql 미리보기 : .query
print(Articles.objects.all().query)
>> 
SELECT 
    "articles_articles"."id", 
    "articles_articles"."title", 
    "articles_articles"."content", 
    "articles_articles"."created_at", 
    "articles_articles"."updated_at" 
FROM 
	"articles_articles"

 

'Django' 카테고리의 다른 글

[Django] ORM update / delete  (0) 2023.03.29
[Django] ORM 실습  (0) 2023.03.28
[Django] ValueError  (0) 2023.03.24
[Django] OperationalError  (0) 2023.03.24
[Django] Django Model  (0) 2023.03.24