Database
[DATABASE] Raw SQL에서 ORM으로 바꾸자
foxlee
2021. 11. 1. 16:27
1. 코드 비교
### insert many
# Raw SQL
cur = conn.cursor()
sql = "INSERT into action(name) values (%s)"
cur.executemany(sql, (names))
conn.commit()
# ORM
actions = [ActionModel(name) for name in names]
db.session.add_all(actions)
db.session.commit()
### get
# Raw SQL
cur = conn.cursor()
sql = "SELECT * FROM action"
cur.execute(sql)
conn.commit()
# ORM
action = ActionModel.query.all()
### Create
# Raw SQL
cur = conn.cursor()
sql = "INSERT into action(name) values (%s)"
cur.execute(sql, (name))
conn.commit()
# ORM
action = ActionModel(name)
action.create()
db.session.commit()
### delete many
# Raw SQL
cur = conn.cursor()
sql = f"""
DELETE FROM action
WHERE id in ({','.join(str(id) for id in ids)}
"""
cur.execute(sql)
conn.commit()
# ORM
db.session.query(ActionModel).filter(ActionModel.id.in_(ids)).delete()
왜 Raw SQL 만 그동안 썼지?
- 처음 Flask를 배울때 튜토리얼(sqlalchemy 사용)를 따라할 당시를 제외하곤 Raw SQL로 주로 개발을 했었다.
- 지금 생각해보면 Raw SQL 를 썼던 이유는
- DB CONNECTION 설정이 API APP과 설정 없이 단독?으로 사용가능하기에 처음 적용하기가 편하다.
- 실제로 ORM 으로 바꾸는 과정에서 APP에 등록하고, APP에 등록된 DB 객체는 백그라운 작업에서 안되서 별도로 디비 세션을 만들었음
- 막연히 ORM 은 쿼리가 복잡해지면 성능 저하 등의 이슈?
- 사실 지금까지 회사에서 진행했던, 또는 개인으로 진행했던 프로젝트 중에서 테이블이 복잡했던 경우는 거의 없었다. 그럼에도 회사에서도 Raw SQL로 데이터베이스 조작했음..(내가 맡았던 프로젝트 내에서)
- SQL 쿼리는 직접 써보고 배울 수 있다?
- 이 이유가 제일 컸다.
- 처음 MYSQL을 공부하며 SQL 쿼리를 직접 따라했기에 그걸 따라 개발하는 것이 더 익숙한 느낌?
- DB CONNECTION 설정이 API APP과 설정 없이 단독?으로 사용가능하기에 처음 적용하기가 편하다.
Why ORM? - (ORM 으로 변경 전 들었던 생각)
- 테이블이 늘어나고 대부분의 CRUD 의 반복되는 SQL 쿼리에 불필요한 코드가 점점 늘어났음
- 테이블이 추가되고, 컬럼이 추가되고, 조건 등이 많아지면서 중복되는 문자열이 늘어나고, 테이블마다 다른 컬럼, 조건이 있어, 쿼리문 만드는 함수를 다양한 케이스에 적용하기가 쉽지 않았음, 어떻게 보면 함수로만 이걸 해결하려다보니 중복이 계속 발생한 듯.
ORM(Object Relational Mapping)으로 바꾸며..
- 좋았던 부분
- 디비 테이블을 클래스 모델로 만들고 같은 기능의 경우 상속하여 코드의 양을 줄일 수 있었다.
- __repr__ 를 통해 로그 확인 시 편리했다.
- 테이블 스키마의 가독성이 많이 좋아짐
- 힘들었던 부분
- 초기 설정이 생각보다 쉽진 않았다. 전에 튜토리얼을 진행할때에는 설정을 따라만 하다보니 어려웠던 기억이 없는데, 실제 API APP에서의 DB 객체와 백그라운드 작업으로 DB 세션 객체와 테스트용 sqlite로 각기 적용하다보니 생각보다 시간이 많이 소비되었다. 특히 백그라운드 작업을 위한 db 세션 객체를 따로 만들어야한다는 것..
- 부족한 부분, 개선이 필요한 부분
- production, db, test 용 db url를 문자열 상수로 임포트하고 있는데 config 객체로 변경하자 https://flask.palletsprojects.com/en/2.0.x/config/
- migrate 로 변경사항 적용해보자 - https://wikidocs.net/81045