한 걸음씩
[Django] ORM 본문
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 실습 사전 준비
- 2023.03.21 - [Django] - django shell_plus
- 위의 설명따라 shell_plus 설치 후 pip freeze > requirements.txt
► 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 관련 문서
- https://docs.djangoproject.com/en/3.2/topics/db/queries/
- https://docs.djangoproject.com/en/3.2/ref/models/querysets/
► Field lookups
- 특정 레코드에 대한 조건을 설정하는 방법
- QuerySet 메서드 filter(), exclude() 및 get()에 대한 키워드 인자로 지정됨
- https://docs.djangoproject.com/en/3.2/topics/db/queries/
# 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 |