[2024.03.25] ORM

체리마루·2024년 3월 25일

ORM

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

  • ORM의 역할

QuerySet API

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


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

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

  • QuerySet API는 python의 모델 클래스와 인스턴스를 활용해 DB에 데이터를 저장, 조회, 수정, 삭제하는 것

QuerySet API 실습

Create

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

  • Django shell 실행




  • save(): 객체를 데이터베이스에 저장하는 메서드

Read

  • 대표적인 조회 메서드

  • all()

  • filter()

  • get()

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

Update

Delete

참고

  • ORM, QuerySet API를 사용하는 이유
    1) 데이터베이스 쿼리를 추상화하여 Django 개발자가 데이터베이스와 직접 상호작용하지 않아도 되도록 함
    2) 데이테베이스와의 결합도를 낮추고 개발자가 더욱 직관적이고 생산적으로 개발할 수 있도록 도움
In [3]: article = Article()

In [4]: article.title = 'first'

In [5]: article.content = 'django!'

In [6]: article.save()

In [7]: article
Out[7]: <Article: Article object (1)>

In [8]: Article.objects.all()
Out[8]: <QuerySet [<Article: Article object (1)>]>

In [9]: article.created_at
Out[9]: datetime.datetime(2024, 3, 25, 5, 39, 38, 544561, tzinfo=datetime.timezone.utc)

In [10]: article = Article(title='second', content='django!!')

In [11]: article.title
Out[11]: 'second'

In [12]: article.content
Out[12]: 'django!!'

In [13]: article
Out[13]: <Article: Article object (None)>

In [14]: article.save()

In [15]: article.pk
Out[15]: 2

In [16]: article.id
Out[16]: 2

In [17]: Article.objects.create(title='third', content='django!!!')
Out[17]: <Article: Article object (3)>

In [18]: Article.objects.all()
Out[18]: <QuerySet [<Article: Article object (1)>, <Article: Article object (2)>, <Article: Article object (3)>]>

In [19]: articles = Article.objects.all()

In [20]: for article in articles:
    ...:     print(article)
    ...: 
Article object (1)
Article object (2)
Article object (3)

In [21]: for article in articles:
    ...:     print(article.title)
    ...: 
first
second
third

In [22]: Article.objects.filter(content='django!')
Out[22]: <QuerySet [<Article: Article object (1)>]>

In [23]: Article.objects.filter(content='django!!')
Out[23]: <QuerySet [<Article: Article object (2)>]>

In [24]: Article.objects.filter(title='first')
Out[24]: <QuerySet [<Article: Article object (1)>]>

In [25]: Article.objects.get(pk=1)
Out[25]: <Article: Article object (1)>

In [26]: article = Article.objects.get(id=1)

In [27]: article.title
Out[27]: 'first'

In [28]: article.content
Out[28]: 'django!'

In [29]: Article.objects.get(pk=100)
---------------------------------------------------------------------------
DoesNotExist                              Traceback (most recent call last)
Cell In[29], line 1
----> 1 Article.objects.get(pk=100)

File ~\Desktop\ORM\django\05-django-orm\venv\lib\site-packages\django\db\models\manager.py:87, in BaseManager._get_queryset_methods.<locals>.create_method.<locals>.manager_method(self, *args, **kwargs) 
     85 @wraps(method)
     86 def manager_method(self, *args, **kwargs):
---> 87     return getattr(self.get_queryset(), name)(*args, **kwargs)

File ~\Desktop\ORM\django\05-django-orm\venv\lib\site-packages\django\db\models\query.py:637, in QuerySet.get(self, *args, **kwargs)
    635     return clone._result_cache[0]
    636 if not num:
--> 637     raise self.model.DoesNotExist(
    638         "%s matching query does not exist." % self.model._meta.object_name
    639     )
    640 raise self.model.MultipleObjectsReturned(
    641     "get() returned more than one %s -- it returned %s!"
    642     % (
   (...)
    645     )
    646 )

DoesNotExist: Article matching query does not exist.

In [30]: Article.objects.filter(content='django!')
Out[30]: <QuerySet [<Article: Article object (1)>]>

In [31]: Article.objects.get(title='first')
Out[31]: <Article: Article object (1)>

In [32]: article = Article.objects.get(pk=3)

In [33]: article.pk
Out[33]: 3

In [34]: article.title = 'ssafy'

In [35]: article.save()

In [36]: article.title
Out[36]: 'ssafy'

In [37]: article = Article.objects.get(pk=2)

In [38]: article.pk
Out[38]: 2

In [39]: article.delete()
Out[39]: (1, {'articles.Article': 1})

In [40]: Article.objects.get(pk=2)
---------------------------------------------------------------------------
DoesNotExist                              Traceback (most recent call last)
Cell In[40], line 1
----> 1 Article.objects.get(pk=2)

File ~\Desktop\ORM\django\05-django-orm\venv\lib\site-packages\django\db\models\manager.py:87, in BaseManager._get_queryset_methods.<locals>.create_method.<locals>.manager_method(self, *args, **kwargs) 
     85 @wraps(method)
     86 def manager_method(self, *args, **kwargs):
---> 87     return getattr(self.get_queryset(), name)(*args, **kwargs)

File ~\Desktop\ORM\django\05-django-orm\venv\lib\site-packages\django\db\models\query.py:637, in QuerySet.get(self, *args, **kwargs)
    635     return clone._result_cache[0]
    636 if not num:
--> 637     raise self.model.DoesNotExist(
    638         "%s matching query does not exist." % self.model._meta.object_name
    639     )
    640 raise self.model.MultipleObjectsReturned(
    641     "get() returned more than one %s -- it returned %s!"
    642     % (
   (...)
    645     )
    646 )

DoesNotExist: Article matching query does not exist.

In [41]: Article.objects.create(title='aaa', content='aaa')
Out[41]: <Article: Article object (4)>

In [42]: article = Article.objects.get(pk=4)

In [43]: article.pk
Out[43]: 4

In [44]: article.delete()
Out[44]: (1, {'articles.Article': 1})

In [45]: Article.objects.create(title='bbb', content='bbb')
Out[45]: <Article: Article object (5)>

In [46]: Article.objects.filter(content__endswith='!')
Out[46]: <QuerySet [<Article: Article object (1)>, <Article: Article object (3)>]>

In [47]: exit()
(venv)
profile
멋쟁이 토마토 개발자 🍅

0개의 댓글