728x90
[TOC]
SQL with django ORM
기본 준비 사항
# 폴더구조
99_sql # only SQL
hellodb.csv
tutorial.sqlite3
users.csv
99_sql_orm # SQL + ORM
...
users.csv # 해당 디렉토리로 다운로드
- django app
- 가상환경 세팅
- 패키지 설치
- migrate
$ python manage.py sqlmigrate users 0001
db.sqlite3
활용sqlite3
실행$ ls db.sqlite3 manage.py ... $ sqlite3 db.sqlite3
- csv 파일 data 로드
sqlite > .tables auth_group django_admin_log auth_group_permissions django_content_type auth_permission django_migrations auth_user django_session auth_user_groups auth_user_user_permissions users_user sqlite > .mode csv sqlite > .import users.csv users_user sqlite > SELECT COUNT(*) FROM users_user; 100
- 확인
- sqlite3에서 스키마 확인
sqlite > .schema users_user CREATE TABLE IF NOT EXISTS "users_user" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "first_name" varchar(10) NOT NULL, "last_name" varchar(10) NOT NULL, "age" integer NOT NULL, "country" varchar(10) NOT NULL, "phone" varchar(15) NOT NULL, "balance" integer NOT NULL);
문제
아래의 문제들을 보면서 서로 대응되는 ORM문과 SQL문을 작성하시오.
vscode 터미널을 좌/우로 나누어 진행하시오. (sqlite / shell_plus)
.headers on
만 켜고 작성해주세요.
1. 기본 CRUD 로직
- 모든 user 레코드 조회
-- sql SELECT * FROM users_user;
# orm User.objects.all() print(User.objects.all().query) # 궁금하면 처보세요
- user 레코드 생성
-- sql INSERT INTO users_user (first_name, last_name, age, country, phone, balance) VALUES ('홍','길동',100,'제주도','010-1234-1234',100000);
- 하나의 레코드를 빼고 작성 후
NOT NULL
constraint 오류를 orm과 sql에서 모두 확인 해보세요.
- 하나의 레코드를 빼고 작성 후
# orm User.objects.create( first_name='홍', last_name='길동', age=100, country='제주도', phone='010-1234-1234', balance=100000 )
- 해당 user 레코드 조회
101
번 id의 전체 레코드 조회
# orm User.objects.get(pk=101)
-- sql SELECT * FROM users_user WHERE id=1001;
- 해당 user 레코드 수정
- ORM:
101
번 글의last_name
을 '김' 으로 수정 - SQL:
101
번 글의first_name
을 '철수' 로 수정
# orm user = User.objects.get(pk=1001) user.last_name = '김' user.save() user.last_name
-- sql UPDATE users_user SET first_name='철수' WHERE id=1001; SELECT * FROM users_user WHERE id=1001;
- ORM:
- 해당 user 레코드 삭제
- ORM:
101
번 글 삭제 SQL
:101
번 글 삭제 (ORM에서 삭제가 되었기 때문에 아무런 응답이 없음)
# orm User.objects.get(pk=1001).delete()
- ORM:
```sql
-- sql
DELETE FROM users_user
WHERE id=1001;
2. 조건에 따른 쿼리문
- 전체 인원 수
User
의 전체 인원수
# orm len(User.objects.all()) User.objects.count()
-- sql SELECT COUNT(*) FROM users_user;
- 나이가 30인 사람의 이름
ORM
:.values
활용- 예시:
User.objects.filter(조건).values(컬럼이름)
- 예시:
# orm User.objects.filter(age=30).values('first_name') #영환씨를 뽑고싶다.(첫번째 값을 뽑고싶다.) User.objects.filter(age=30).values('first_name')[0].get('first_name')
-- sql SELECT first_name FROM users_user WHERE age=30;
- 나이가 30살 이상인 사람의 인원 수
- ORM:
__gte
,__lte
,__gt
,__lt
-> 대소관계 활용
# orm #gte 이상 #lte 이하 #gt 초과 #lt 미만 User.objects.filter(age__gte=30).count()
-- sql SELECT count(*) FROM users_user WHERE age >= 30;
- ORM:
- 나이가 20살 이하인 사람의 인원 수
-- sql SELECT count(*) FROM users_user WHERE age <= 20; -- sql 문에서 같지 않음을 표현할 때는 -- != 또는 <>를 사용합니다.
# orm User.objects.filter(age__lte=20).count()
- 나이가 30이면서 성이 김씨인 사람의 인원 수
-- sql SELECT count(*) FROM users_user WHERE age = 30 AND last_name='김';
# orm User.objects.filter(age=30, last_name='김').count()
- 나이가 30이거나 성이 김씨인 사람?별도로 import해서 사용해야합니다.
# orm from django.db.models import Q Q(age=30) Q(last_name='김') User.objects.filter(Q(age=30) | Q(last_name='김')).count() #query 확인 print(User.objects.filter(Q(age=30) | Q(last_name='김')).query)
-- sql SELECT * FROM users_user WHERE age>=30 OR last_name='김';
from django.db.models import Q Model.objects.filter(Q(x=1)|Q(y=2))
- : OR을 활용하고 싶다면, Q 오브젝트를 사용해야합니다.
- 지역번호가 02인 사람의 인원 수
ORM
:__startswith
# orm #__startswith ~으로 시작하는 User.objects.filter(phone__startswith='02-').count()
-- sql SELECT COUNT(*) FROM users_user WHERE phone LIKE '02-%';
- 거주 지역이 강원도이면서 성이 황씨인 사람의 이름
-- sql SELECT first_name FROM users_user WHERE country='강원도' AND last_name='황';
# orm User.objects.filter(country='강원도', last_name='황').values('first_name') #한명만일떄 User.objects.filter(country='강원도', last_name='황')[0].first_name # User.objects.filter(country='강원도', last_name='황').values('first_name')[0].get('first_name')
3. 정렬 및 LIMIT, OFFSET
- 나이가 많은 사람순으로 10명
-- sql SELECT * FROM users_user ORDER BY age DESC LIMIT 10;
# orm User.objects.order_by('-age')[:10] # 정말 10개인지 확인 User.objects.order_by('-age')[:10].count()
- 잔액이 적은 사람순으로 10명
-- sql SELECT * FROM user_user ORDER BY balance LIMIT 10;
# orm User.objects.order_by('balance')[:10]
- 잔고는 오름차순, 나이는 내림차순으로 10명?
# orm User.objects.order_by('balance', '-age')[:10]
```sql
-- sql
SELECT *
FROM users_user
ORDER BY balance ASC, age DESC
LIMIT 10;
- 성, 이름 내림차순 순으로 5번째 있는 사람
# orm User.objects.order_by('-last_name', '-first_name')[4]
```sql
-- sql
SELECT *
FROM users_user
ORDER BY last_name DESC, first_name DESC
LIMIT 1 OFFSET 4;
4. 표현식
ORM:
aggregate
사용https://docs.djangoproject.com/en/3.1/topics/db/aggregation/#aggregation
- '종합', '합계' 등의 사전적 의미
- 특정 필드 전체의 합, 평균 등을 계산할 때 사용
- 전체 평균 나이
-- sql SELECT AVG(age) FROM users_user;
# orm from django.db.models import Avg #Avg('age') 형태로 값을 구하고.. #annotate로 필드를 추가합니다. User.objects.annotate(my_awesome_avg=Avg('age')).values()[0] User.objects.annotate(Avg('age')).values()[0]
- 김씨의 평균 나이
-- sql SELECT AVG(age) FROM users_user WHERE last_name='김';
# orm User.objects.filter(last_name='김').aggregate(Avg('age'))
- 강원도에 사는 사람의 평균 계좌 잔고
-- sql SELECT AVG(balance) FROM users_user WHERE country='강원도';
# orm User.objects.filter(country='강원도').aggregate(Avg('balance'))
- 계좌 잔액 중 가장 높은 값
-- sql SELECT MAX(balance) FROM user_user;
# orm User.objects.aggregate(Max('balance')) #User.objects.aggregate(Max('balance'))
- 계좌 잔액 총액
-- sql SELECT MAX(balance) FROM users_user
# orm from django.db.models import Q, Max, Avg, Sum, .... User.objects.aggregate(Sum('balance'))
728x90
'SSAFY > Django' 카테고리의 다른 글
[Django] 로그인한 사용자 판별하기 (0) | 2021.03.27 |
---|---|
[Django] 댓글 삭제 (0) | 2021.03.26 |
[DJANGO] 댓글 만들기 (0) | 2021.03.25 |
[Django] 회원가입 만들기 (0) | 2021.03.22 |
[Django]Form (0) | 2021.03.21 |