내 잡다한 노트
ORM 본문
ORM : Object Relational Mapping
객체-관계 매핑의 줄임말이다.
객체라는 개념을 구현한 클래스와 RDB(Relational DataBase)에서 쓰이는 데이터인 테이블을
'자동'으로 매핑하는 것을 의미한다.
서로가 기존부터 호환가능성을 두고 만들어진 것이 아니라 불일치가 발생하는데,
이를 ORM을 통해 객체 간의 관계를 바탕으로 SQL문을 자동으로 생성해 불일치를 해결한다.
ORM을 이용하면 따로 SQL문을 짤 필요없이 객체를 통해 간접적으로 DB를 조작할 수 있다.
데이터를 서로 교류하는 시스템간에 사용하는 언어가 다르거나 조금씩 데이터를 기술하는
방식이 다르기에 시스템이 변경되더라도 이를 하나의 코드로 통합해서 사용할 수 있는
기술이 필요했다. 이 개념을 기존의 Object의 개념과 연결해서 하나의 클래스가
하나의 실제 시스템 자료구조에 연결되도록 추상화를 해서 연결한 것.
데이터베이스의 스키마(db에 저장될 데이터 형태와 속성의 집합)를 소스코드로 기술하고
재사용할 수 있도록 하는 것으로 이해하자.
장점)
SQL문이 아닌 클래스의 메소드를 통해 DB를 조작할 수 있다.
그래서 개발자가 객체 모델만 이용해서 프로그래밍을 하는 데 집중할 수 있다.
SQL 문을 사용하면서 같이 필요한 선언문, 할당, 종료 같은 부수적인 코드가 사라지거나 줄어든다.
객체로 작성돼 재사용이 용이하고 리팩토링이 용이함.
단점)
편리하지만 그만큼 신중하게 설계해야 한다.
프로젝트의 복잡성이 커질 수록 난이도도 올라가고 부족한 설계로 잘못 구현됐을 경우
속도저하 및 일관성을 무너뜨리는 문제점이 생길 수 있다.
다음과 같은 특성에서 객체-관계 간의 불일치가 생긴다.
세분성 : 경우에 따라 DB에 있는 테이블 수보다 더 많은 클래스를 가진 모델이 생길 수 있다.
상속성 : RDBMS는 상속 개념이 없다.
- 터미널에서 쟝고 콘솔에 들어갑니다. (python manage.py shell)
- 레스토랑 정보를 3개 추가합니다.
>> from third.models import Restaurant
>> Restaurant(name=’Deli Shop’, address=’Gangnam’).save()
>> Restaurant(name=’Korean Food’, address=’Gangbuk’).save()
>> Restaurant(name=’Sushi’, address=’Gangbuk’).save()
- 이렇게 입력된 데이터는 다음의 코드로 조회할 수 있습니다.
>> Restaurant.objects.all()
>> Restaurant.objects.all().values()
- 정렬 순서를 바꾸고 싶으면 order_by 메소드를 사용합니다.
>> Restaurant.objects.order_by('-created_at').values() # 최신순
>> Restaurant.objects.order_by('name').values() # 이름순
- 하나의 오브젝트를 선택하고 싶으면 primary key 기준으로 get 메소드를 사용합니다. (primary key는 그 레코드의 고유한 값 식별 값을 의미합니다. 쟝고에선 우리가 따로 설정하지 않아도 자동으로 매겨줍니다.)
>> Restaurant.objects.get(pk=1).name
>> Restaurant.objects.get(pk=2).address
>> item = Restaurant.objects.get(pk=3)
>> item.name
#데이터 필터링
필터링하는 메소드로 filter, exclude를 사용할 수 있다.
filter는 조건에 해당하는 것을 추리는 거고, exclude는 조건에 해당하는 것은 제외한 것들을 보여준다
ex) Restaurant.objects.filter(name='Deli Shop').values()
위 메소드들은 QuerySet을 리턴한다. 쿼리셋은 실제 데이터를 읽기 전까지 db에서 실행되지 않기
때문에 chaining이 가능하다. (쿼리란 질의라는 뜻으로 db에 어떤 데이터를 받아오고 싶은지
조건 정의하는 것을 의미한다.)
# 페이징하기
데이터가 많아지면, 10개 또는 20개씩 끊어서 볼 방법이 필요하다.
Restaurant.objects.all()[0:1] # start 0, end 1
그럴땐 위 코드처럼 [x:y] 슬라이싱을 사용하자.
#Field Lookup으로 복잡한 조건 검색하기
기본적으로 Field lookup은 다음과 같이 사용한다.
Restaurant.objects.filter(name__exact=’Korean Food’)
위 방식은 filter를 쓸 때와 같은 효과를 지닌다. 즉, filter 메소드에는 __exact가 숨겨져 있는 것이다.
자주 쓰이는 메소드라 굳이 쓸 필요없이 줄인 듯하다.
아무튼, 위와 같이 filter, exclude나 get 메소드 내에 검색을 원하는 필드명과 filed lookup을 붙여서
값을 전달한다.
field이름__조건 키워드
contains : 특정 키워드가 포함된 레코드를 조회
Restaurant.objects.filter(name__contains=’Korea’).values()
exact : 특정 키워드랑 정확하게 일치하는 레코드 조회
gt, gte, lte, lt : greater than, less than 의 줄임말 뒤에 e는 equal
Restaurant.objects.filter(created_at__lt='2018-01-01 00:00:00').values()
startswith, endswith : 특정 문자열로 시작하거나 종료되는 레코드를 조회
Restaurant.objects.filter(name__startswith='Korea').values()
in : 여러 값을 한번에 검색에 조건으로 걸 때 사용
Restaurant.objects.filter(id__in=[1,3]).values()
range : 특정 값 사이의 레코드를 조회
Restaurant.objects.filter(created_at__range=(start_date, end_date)).values()
# 데이터 수정/삭제
UPDATE : 수정하기
우리가 이미 배운 데이터를 조회하는 방식을 써서 원하는 데이터를 가져온 후에
속성값을 변경하고 데이터를 추가했을 때 처럼 save를 호출하면 수정이 완료된다.
save를 호출할 때 데이터를 추가하는 insert인지, 데이터를 수정하는 update인지 어떻게 구분할까?
모델의 인스턴스에 id (primary key) 값이 지정돼 있으면 save를 호출시 update로 인식하고 수행한다.
존재하지 않는다면 새로운 값이니 insert한다.
delete : 삭제하기
item.delete()
조회한 레코드에서 delete를 호출하면 삭제가 된다.
'Web > Django' 카테고리의 다른 글
Relation과 Join (0) | 2022.04.18 |
---|---|
CRUD (0) | 2022.04.17 |
Form (0) | 2022.04.11 |
모델 (0) | 2022.04.10 |
3번째 챕터를 보고 기억해둘 부분들 (0) | 2022.04.09 |