[Django] Django ORM을 사용해서 DB CRUD 구현하기

[Ted's Log] 테드로그·2021년 8월 22일
3
post-thumbnail

👋   ORM이란?

  ORM(Object Relational Mapping)이란 객체(Object)와 관계형 데이터베이스(Relational)을 연결(Mapping)한다는 의미이다. 즉 객체 지향 프로그래밍(Object-oriented programming) 언어에서 Class 기반으로 데이터 모델을 만들고, CRUD와 같이 데이터를 다루는 작업을 수행할 수 있도록 도와주는 것이 ORM이라고 보면 된다. 프로그래머 입장에서 ORM은 프로젝트 개발에 쓰이는 동일한 프로그래밍 언어로 데이터를 다룰 수 있어 보다 더 비즈니스 로직에 집중할 수 있게 되고, 유지 보수가 수월한 코드를 생산할 수 있게 된다는 장점이 있다.

   cf. ORM을 제공하는 프레임워크 목록

✈️   Django ORM

  Django는 models 모듈을 통해서 ORM과 관련된 기능을 제공한다. 장고 프로젝트에서 어플리케이션을 생성하게 되면 기본적으로 생성되는 파일 중에 models.py 파일이 있는데 이곳에서 데이터베이스에 추가할 table을 class 형태로 만들게 된다. 해당 class는 models.Model을 상속받아야 한다.

  장고는 생성한 데이터 모델 객체를 다른 파일에서 참조할 수 있도록 Manager를 제공하는데 objects라는 명칭으로 사용할 수 있다. View 파일 혹은 Shell에서 모델 클래스를 참조하고 싶을 때, Manager를 통해서 싱글톤 패턴의 class를 참조하는 형식과 비슷하게 사용할 수 있다.
  objects 다음에 호출하게되는 함수들이 QuerySet APIs이다. API 사용자가 데이터베이스에서 원하는 동작을 수행하기 위해 필요한 쿼리문으로 바꿔주는 역할을 한다고 보면 된다. 함수들에 대한 자세한 내용은 공식 Documentation에서 확인할 수 있다. 이번 포스팅에서는 CRUD에 필수적인 역할을 하는 기본 QuerySet API에 대해서 알아볼 것이다.


➕   데이터 추가하기 (Create)

  models.py에서 class를 통해 table을 생성했다면, 해당 테이블에 데이터를 추가하는 작업이 가장 선행되어야 한다. QuerySet API 에서 데이터 생성을 위한 create 함수를 제공한다. 함수의 인자로 객체의 필드에 해당하는 데이터를 전달하면 입력된 데이터가 table에 추가된다.
   create 함수를 사용하지 않고 class의 객체를 생성자로 생성하면서 데이터를 테이블에 저장하는 방식이 있다. 마찬가지로 객체를 생성하면서 데이터를 인자로 전달하면 된다. 그 후에는 save 함수를 실행해야지 데이터베이스에 저장된다.


🧐   데이터 조회하기 (Read)

  조건에 맞는 데이터를 가지고오기 위해서 여러가지 쿼리셋 함수를 실행할 수 있다. 우선 all 함수를 통해 호출한 객체의 모든 데이터를 쿼리셋 형태로 조회할 수 있다.
  values 함수를 통해 데이터를 조회하게 되면 딕셔너리 형태의 데이터 리스트를 담고있는 쿼리셋을 반환받게 된다. HTTP 통신할 때, JSON 형태로 변환이 가능해서 많이 사용하게 되는 함수이다.
  조회한 데이터에서 key를 제외하고 value만 확인하고 싶을때는 value_list 함수를 사용할 수 있다. 함수 실행 결과로 테이블의 데이터를 튜플 형태의 리스트로 담은 쿼리셋을 전달받게 된다.
  테이블의 모든 데이터를 조회하는 것이 아닌, 특정 조건에 해당하는 데이터를 조회하기 위해서 get 함수를 사용할 수 있다. 주의할 부분은 unique한 데이터를 조회하기 위해 get 함수를 사용해야 한다는 점이다. 데이터를 조회하지 못하면 Model.DoesNotExist 예외가, unique 데이터를 찾지 못하고 여러 개가 조회된다면 Model.MultipleObjectsReturned 예외가 발생하게 된다.
  조건을 만족하는 하나의 데이터가 아닌 여러개의 데이터를 조회하고자 할 때 filter 함수를 사용할 수 있다. filter 함수에 인자를 여러개 전달하면 해당 조건을 모두 만족하는 데이터를 조회하게 된다. 만약 or 논리 형식으로 데이터를 조회하고자 한다면 Q objects를 import 해야 한다.
  특정 조건을 만족하지 않는 데이터를 조회하는 것도 가능하다. exclude 함수를 통해서 조회할 수 있다.


✂️   데이터 수정하기 (Update)

  데이터를 수정하기 위해서 update 함수를 사용할 수 있다. 수정할 데이터의 개수와는 상관 없이 일괄 수정이 가능한 특징을 가지고 있다. 함수 실행 결과로 영향을 받게 된 row의 숫자를 반환하게 된다.
  다른 수정 방법으로, 앞서 데이터를 생성할 때 객체의 인스턴스를 직접 만들고 호출했던, save 함수를 사용할 수 있다.
  위의 코드에서 확인할 수 있듯이 save 함수를 통해서 데이터를 수정하는 경우 메모리에 데이터 객체를 할당하는 과정이 수반된다. 따라서 단순히 데이터를 수정하는 작업 외에 모델 객체를 사용하는 것이 아니라면 불필요한 메모리 부하를 줄이기 위해서 update 함수를 사용하는 것이 권장된다.


➖   데이터 삭제하기 (Delete)

  데이터를 삭제하고자 하는 경우에는 delete 함수를 호출하면 된다. update와 마찬가지로 삭제할 데이터의 개수와 상관없이 사용할 수 있다. 함수 실행 결과로 삭제된 객체의 수와 삭제된 객체가 속해있던 모델 클래스에서 몇개가 삭제되었는지 딕셔너리로 반환해준다.
  위의 코드에서 Movie 클래스에서 생성된 데이터를 모두 삭제했는데, Movie_actors 클래스에서도 5개의 데이터가 삭제된 것을 확인할 수 있다. 이는 Django QuerySet API delete로 삭제된 객체가 연관되어 있는 다른 테이블서도 삭제되도록 기본 설정이 되어 있기 때문이다.

😎   Conclusion

  이번 포스팅을 통해 Django Framework가 백엔드 영역에서 데이터를 다룰 때에 작동하는 원리와 구조를 이해할 수 있었다. 장고의 기초에 대해 알게 되었으니, 백엔드 개발자로서의 여정을 더욱 힘차게 나아갈 준비를 마친 것 같다. 앞으로 장고 프레임워크의 심화된 내용에 대해서도 알차게 다루어보겠다.


참고자료

https://docs.djangoproject.com/en/3.2/topics/db/models/
https://docs.djangoproject.com/en/3.2/topics/db/managers/
https://docs.djangoproject.com/en/3.2/ref/models/querysets/

profile
성장하는 개발자가 되기 위한 발자취 🧑🏻‍💻

0개의 댓글