TIL65. Django : SQL과 Django ORM의 관계
📌 이 포스팅에서는 Django의 ORM 문법과 SQL문법에 대해 비교 정리하였습니다.
🌈 SQL과 Django ORM의 관계
🔥 SELECT 구문
🔥 WHERE 구문
🔥 CREATE 구문
🔥 UDATE 구문
🔥 DELETE 구문
1. SELECT 구문
🤔 모든 row를 가져올 때, all()
✔️ Person이란 table에서 모든 column을 기준으로 모든 row 가져올 때 SQL문법에서는 아래와 같은 문법을 사용한다.
mysql> SELECT * FROM Person;
✔️ ORM으로 사용하면 아래와 같다. 해당 table 모든 row를 가져왔기 때문에 for문 사용하여 객체를 1개씩 순회 가능하다.
all_data = Person.objects.all() for data in all_data: print(data.name) print(data.email) print(data.age)
🤔 특정 row만 가져올 때, only()
✔️ 모든 row에 대해서 특정 column만 조회하고 싶다면, SQL문법에서 * 대신 해당 column을 지정해준다.
mysql> SELECT name, age FROM Person;
✔️ ORM으로 모든 row에 대해서 특정 column만 조회하고 싶다면, only를 사용합니다.
Person.objects.only('name', 'age')
🤔 지정된 column들의 중복을 제거한 row만 필요할 때, distinct()
✔️ column을 지정하여 중복된 값을 제외시킨 row를 가져올 때는 DISTINCT를 사용합니다.
✔️ 아래 명령은 name과 age의 컬럼의 모든 row들 중 중복을 제외한 row를 읽어드립니다.
mysql > SELECT DISTINCT name, age FROM Person;
✔️ ORM으로 구현하면 아래와 같습니다. 값들의 중복을 체크하기 때문에 values와 함께 사용합니다.
Person.objects.values('name', 'age').distinct()
🤔 row의 양을 제한할 땐 슬라이싱
✔️ 가져올 row의 갯수는 LIMIT을 통해 제한할 수 있다.
mysql> SELECT * FROM Person LIMIT 10;
✔️ ORM으로 row의 수를 제한하려면 슬라이싱 사용한다.
limit_data = Person.objects.all()[:10]
✔️ SQL에서 시작점을 지정할 때는 OFFSET을 사용한다. 5로 지정되면 6번째 row부터 10개의 row의 읽어드린다.
mysql > SELECT * FROM Person OFFSET 5 LIMIT 10;
✔️ ORM으로 제어하면 슬라이싱을 사용하면 된다.
limit_data = Person.objects.all()[5:10]
2. WHERE 구문
🤔 조건에 해당되는 row를 가져올 때,, filter()
✔️ SQL의 WHERE은 조건을 걸어 해당하는 조건의 값들만 걸러낼 수 있다.
✔️ 비교연산자를 통해 어떤 기준보다 크거나 작은, 또는 기준이 아닌 값들만도 필터할 수 있다.
mysql > SELECT * FROM Person WHERE id = 1; 👈 id값이 1인 row mysql > SELECT * FROM Person WHERE age > 18; 👈 age값이 18보다 큰 row들 mysql > SELECT * FROM Person WHERE age <= 18; 👈 age값이 18보다 작거나 같은 row들 mysql > SELECT * FROM Person WHERE age != 18; 👈 age값이 18이 아닌 row들
✔️ ORM으로는 언더바 2개(__)를 통해 비교연산자와 같은 기능을 사용할 수 있다.
Person.objects.filter(age__gt=18) 👈 age값이 18보다 큰 row들 Person.objects.filter(age__gte=18) 👈 age값이 18과 크거나 같은 row들 Person.objects.filter(age__lt=18) 👈 age값이 18보다 작은 row들 Person.objects.filter(age__lte=18) 👈 age값이 18보다 작거나 같은 row들 Person.objects.filter(age!=18) 👈 age값이 18이 아닌 row들
🤔 범위를 이용해 WHERE 다룰 땐, BETWWEN ~ AND
✔️ SQL에서 조건을 걸어 만족하는 row만 가져올 때는 BETWEEN ~ AND를 사용한다.
mysql > SELECT * FROM Person WHERE age BETWEEN 10 AND 20;
✔️ ORM에서는 column에 `__range를 걸어 range 함수처럼 사용이 가능하다.
Person.objects.filter(age__range=(10, 20))
🤔 해당 값을 포함하는 속성 값을 가진 row들을 가져올 때,
✔️ SQL에서 like 구문을 이용하면, 속성의 값이 어떤 조건과 해당하는 row들만 제한하여 가져올 수 있다.
✔️ "%"는 글자수를 정해주지 않을 때 사용하고, "_"는 글자 수를 정할 때 사용한다.
✔️ 또한 LIKE 절은 기본적으로 case-insensitive하다. 즉, 대소문자를 구별하지 않는다.
✔️ 따라서 대소문자를 구분하고 싶다면 "biranry"를 추가한다.
mysql > SELECT * FROM Person WHERE name like '%A%'; 👈 name값이 a 또는 A를 포함한 row들 mysql > SELECT * FROM Person WHERE name like 'A%'; 👈 name값이 a 또는 A로 시작하는 row들 mysql > SELECT * FROM Person WHERE name like binary'%A'; 👈 name값이 A로 끝나는 row들
✔️ ORM에서는 특정 값을 기준으로 해당 속성에 포함여부를 가지고 필러링을 할 때 아래와 같은 옵션을 사용한다.
✔️ contains과 icontains 해당 값을 포함하는 row를 필터한다. 이 둘의 차이점은 icontains의 경우 대소문자를 구분하지 않는다는 것이다.
✔️ 즉, ORM에서 기본으로 'case-sensitive'하다. 대소문자를 구분하기 때문에 대소문자를 구분하지 않고 조건을 적용시키고 싶다면 i를 붙인다.
Person.objects.filter(name__icontains='A') 👈 name필드의 값이 a 또는 A를 포함하는 Person.objects.filter(name__contains='A') 👈 name필드의 값이 A를 포함하는 Person.objects.filter(name__istartswith='A') 👈 name필드의 값이 a 또는 A로 시작하는 Person.objects.filter(name__startswith='A') 👈 name필드의 값이 A로 시작하는 Person.objects.filter(name__iendswith='A') 👈 name필드의 값이 a또는 A로 끝나는 Person.objects.filter(name__endswith='A') 👈 name필드의 값이 A로 끝나는
🤔 해당 값과 일치하는 속성 값을 가진 row들만 가져올 때,
✔️ 여러개 값을 주어, 그 값과 일치하는 속성값을 가진 row들을 반환할 때는 IN 구문을 사용한다.
mysql > SELECT * FROM Person WHERE score in ('A', 'B');
✔️ ORM에서도 언더스코어와 in을 사용해서 filter할 수 있다.
Person.objects.filter(score__in=['A', 'B'])
🤔 AND, OR, NOT 을 ORM에서 사용하고 싶을 때,
✔️ SQL에서 여러개의 조건을 걸어줄 때는 AND, OR, NOT을 사용한다.
mysql > SELECT * FROM Person WHERE gender='male' AND age > 25 mysql > SELECT * FROM Person WHERE gender='male' OR age > 25; mysql > SELECT * FROM Person WHERE NOT gender='male';
✔️ ORM에서 이를 사용하려면 아래와 같다. 콤마(,)는 AND, |는 OR, exclude는 NOT을 의미한다.
from django.db.models import Q Person.objects.filter(gender='male', age__gt=25) Person.objects.filter(Q(gender='male') | Q(age__gt=25)) Person.objects.exclude(gender='male')
🤔 정렬해서 가져오고 싶을 때, order_by()
✔️ ORDER BY를 통해 정렬하여 가져올 수 있고, 기본이 오름차순이다.
✔️ 내림차순으로 정렬하고 싶다면 DESC를 붙인다.
mysql > SELECT * FROM Person ORDER BY age; mysql > SELECT * FROM Person ORDER BY age DESC;
✔️ ORM에서는 order_by를 사용한다. 기본이 오름차순이고 내림차순을 원한다면 "-"를 필드명 앞에 붙인다.
Person.objects.order_by('age') Person.objects.order_by('-age')
3. CREATE 구문
🤔 DB에 데이터를 생성할 때는 create()
✔️ SQL에서는 INTO를 통해 데이터를 생성한다.
mysql >INSERT INTO Person VALUES ('Jack', '23', 'male');
✔️ ORM을 이용할 경우, 객체에 create를 사용해 필드에 값을 매핑시켜준다.
Person.objects.create(name='jack', age=23, gender='male)
4. UPDATE 구문
🤔 1개의 row를 수정할 때,
✔️ id값이 1인 row의 age값을 20으로 수정하고자한다면 아래와 같은 SQL문을 사용한다.
mysql > UPDATE Person SET age = 20 WHERE id = 1;
✔️ ORM의 경우, get을 통해 해당 객체를 가져온 뒤, 객체의 필드값에 원하는 값을 넣고 저장한다.
person = Person.objects.get(id=1) person.age = 20 person.save()
🤔 여러개의 row를 수정할 때,
✔️ SQL의 경우 WHERE 구문으로 특정 데이터를 지정하지 않으면 테이블의 모든 필드에 적용시킬 수 있다.
mysql > UPDATE Person SET age = age * 1.5;
✔️ ORM의 경우 F 객체를 가져와 모든 age값에 수정을 적용시킬 수 있다.
✔️ F 객체를 사용하지 않는다면, 모든 객체를 가져와 for문을 돌리며 수정해야 한다.
from django.db.models import F Person.objects.update(age=F('age')*1.5)
5. DELETE 구문
🤔 테이블의 모든 rows를 삭제할 때,
✔️ DELETE를 통해 해당 Table을 지정하면 모두 데이터가 삭제된다.
mysql > DELETE FROM Person;
✔️ all()을 통해 모든 객체를 가져온 뒤, delete로 지워준다.
Person.objects.all().delete()
🤔 특정 row들만 삭제할 때,
✔️ WHERE 구문을 통해 해당 조건에 만족하는 row를 지우는 방법은 아래와 같다.
mysql > DELETE FROM Person WHERE age < 10;
✔️ ORM에서도 filer나 get을 통해 특정 row들을 찾은 후, delete()를 통해 삭제할 수 있다.
Person.objects.filter(age__lt=10).delete()
Author And Source
이 문제에 관하여(TIL65. Django : SQL과 Django ORM의 관계), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@jewon119/TIL53.-Django-SQL과-Django-ORM의-관계-ltlcbikq저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)