본 시리즈의 지난 포스팅에서는 {% block content %} 에 들어갈 내용을 가지고 상술하는 것으로 예고하고 글을 마감하였는데요. 해당 내용에 대해 다루기 위해서 이제, ORM에 대해 먼저 언급할 필요가 있어서 이번 글에서는 ORM 얘기를 이어 나가볼까 합니다.
Django ORM은 편리한가?
End-User와 어느 정도 소통하고, 업데이트가 끊임없이 발생하는 서비스를 만드는데 있어서, DB는 필수 불가결입니다.
정적페이지 하나 띄워놓고 특정 회사나 아이템에 대해 일방적으로 정보를 전달하고 마는 랜딩페이지 같은 것들이라면 당연히, End-User로부터 Data를 받아야 할 일이 없기 때문에, DB가 없어도 서비스가 가능합니다.
하지만, 조금만 기능을 넓히고 서비스영역을 확장하려고 해도 DB는 무조건 필요하게 됩니다.
해서 DB를 만져볼려고 하게 되면, SQL문에 관련된 학습이 필요하다는 사실을 알게 됩니다. 초심자는 여기서 다시 허들을 느낄 수밖에 없습니다. Python도 겨우 다루고 있는 마당에, SQL문을 또 배워야 한다니.. DB는 또 어떻게 다룬다는 것인가.. 엑셀밖에 다뤄본 적 없는데, 보기엔 비슷해도 뭔가 많이 다른 것 같기도 하고.. 참 심하게 당황하게 됩니다.
하지만, Django를 통해 서비스를 빌딩하게 되면, ORM을 통해 DB CRUD가 손쉽게 가능합니다.
ORM에 관해서는 다른 많은 포스팅을 통해 관련 내용을 찾을 수 있기 때문에, 개념에 관해 상술하지는 않겠습니다.
제가 이 시리즈를 통해 전달하고 싶은 가치는 어떻게 하면 빠르게 서비스를 빌딩하고, 그걸 어떻게 운용 해나가는지에 대한 Quick reference라는데 있습니다.
처음부터 완벽한 구조의 코딩을 기대하면 할수록 서비스 개발 속도가 더뎌지는 것은 명백한 사실입니다.
그러한 완벽한 고려를 목적으로 학습하듯 서비스를 개발한다면 개발 기간이 늘어질 수 밖에 없고, 가설을 세우고 검증하기를 수없이 반복해야 하는 상황에서는 적합치 않은 개발방법론이 됩니다.
따라서, 완벽한 코딩 / 성능 좋은 코딩은 일단 제쳐두고, 우리가 이해할 수 있는 선에서 코딩을 먼저 진행하고, 리팩토링은 해당 가설이 성공적으로 검증된 후에 하는 것으로 하고 코드를 짜내기로 합니다.
Django ORM은 SQL문을 따로 배울 필요 없이, DB를 조작할 수 있게 개발자를 도와 줍니다.
실질, ORM이 돌 때 SQL문으로 번역하여 돌기 때문에, ORM이 특별히 다른 방식을 채택해서 DB에 접근하는 것은 아닙니다. 다만, ORM문법 자체가 단순하고, 코딩 시 SQL문과 섞어서 쓰기 위한 많은 문법적 우회책을 요구 받지 않는다는 데서, 빠른 개발을 가능케 도와 줍니다.
ORM만 알아도 DB를 얼마든지 원하는 데로, CRUD할 수 있다는 것만으로도 SQL문을 별도로 숙지할 필요가 사라지기 때문에, 초심자 입장에서는 더욱 유용하다 할 것입니다.
물론, Django ORM에 대해 블로깅하신 분들의 몇몇 글들을 통해, ORM만 알아서는 정교하게 CRUD하기가 어려운 상황들이 있기에, 단점이 존재한다고 지적하는 경우도 보게 됩니다.
하지만, 필장의 입장에서는 이마저도 그리 동감을 가지지는 못합니다.
지난 글에서도 언급하였지만, 유지보수와 코딩의 간결화 측면에서도 Back-end에서 특정 희망 데이터 한 라인을 filtering하기 위해 모든 코드를 짜기 보다는 Back-end에서는 특정할 필요가 있는 조건 중 최대폭의 선에서 통으로 데이터를 뽑아내고, 그걸 통째로 Front-end로 넘긴 후 Front-end에서 Custom Template tag를 활용해 세밀하게 정보를 추출해 내는 방식이 훨씬 성능 및 유지보수 면에서 유리하다는 것을 경험적으로 깨달았기 때문입니다.
그러한 방식을 취해서 빌딩해 오면서, ORM만을 이용해서 복잡한 테이블 참조관계를 가진 경우에도 단 한번도 문제 없이 코딩을 이어왔고, 좋은 성능을 유지하면서 잘 사용하고 있기 때문에, 더욱 그러한 부분에 대해 확신을 갖고 있다 하겠습니다.
아마도, ORM만 써서는 정교하게 데이터를 뽑아내기 어렵다는 단점이 지적되는 이유는 Django Template tag의 사용은 배제하고, Front-end는 JavaScript 주류인 React나 Vue로 구성하고, Back-end 팀과 Front-end 팀이 각기 구사 가능한 기술 stack에만 집중하여 각자 파트에서 필요한 요구사항을 협의하려 하기 때문에 Front-end측에서 데이터 표시를 위해 최종 결과 표출 데이터를 Back-end에서 완전히 찾아내어 Front-end로 전달하게끔 업무가 진행되기 때문이리라 생각됩니다.
이와 같은 협업 구조에서는, Back-end에서의 데이터 특정화를 위한 코딩 부담은 훨씬 증가할 수 밖에 없겠습니다. 당연하게도, Back-end가 더 많은 연산을 요구받을 수록 데이터를 return해 주는데에 있어서도 성능상 영향을 받으리라 생각도 되구요.
여하튼, SQL문을 하나도 몰라도, ORM만 조금만 익히면, DB를 사용해야 하는 기능 개발에 있어서는 아무 문제 없이 진행이 가능합니다.
그럼에도 불구하고, 저 또한 역시 다른 블로거분들과 마찬가지로 SQL문의 기본은 어느 정도 알 필요가 있다고 말씀 드립니다. 우선, SQL문이 학습하기 그리 어렵지가 않습니다. 꽤나 쉬운 문법 형식을 취하고 있고, CRUD가 전부이기에 알아야할 SQL 문법 자체도 꽤나 고정적이고, 많지도 않습니다.
그리고, ORM도 결국 SQL문으로 번역을 돕는 구조이기 때문에, 결국 특정 ORM문법이 SQL문으로 어떻게 대체되느냐에 대해 개념적으로 이해해 두는 것 정도는 Django를 통하지 않고, DB에 직접 접근해 모종의 대량 Data Manipulation 조치가 필요한 상황에서 작업을 빠르게 진행할 수 있게 해줍니다.
이 점 참조하시어, SQL문에 대해 학습할지 여부에 대해 취사선택하시면 되시리라 생각됩니다.
말머리가 좀 길었지만, 요약해서 ORM과 Custom Tags를 통해 얼마든지, 데이터를 세밀하게 뽑아내는데에 문제가 없다라는 점 이해하고 ORM에 대해 계속 얘기해 나가겠습니다.
Django ORM get()과 filter() 메소드
Django ORM이 Lazy-loading을 한다거나, Eager Loading을 한다거나 하는 특성에 대해서는 일단 개념을 제쳐 둡니다.
당연히, 알면 코드가 매우 간결해 지고, 성능도 좋아집니다.
하지만, 우리는 당장 기능개발이 필요하니, 당장은 이해할 수 없는 이러한 개념들은 고려치 않고, 코딩을 진행합니다. 나중에 코딩 중 에러 메시지를 뱉어낼 때 해당 에러메시지를 보면서, 자연스럽게 이에 대해 이해하게 되고, 스스로 리팩토링을 진행하게 되기 때문에, 자연스러운 체감을 획득한 이후에 코드를 수정하는 걸로 하고, 일단은 진행을 합니다.
제가 Django ORM을 처음 접하고 Back-end 코드를 짤 때, 가장 접합과 동시에 헷갈렸던 부분이 get()과 filter()를 이용해 queryset을 뽑아낼 때의 차이와 어떤 상황에서 써야 하는지에 대한 용법에 관한 부분이었습니다.
데이터를 추출하는데 있어, 무슨 차이가 있어서 그리 만들어 뒀는지 알 수 없었고, 심지어 filter()를 통해 뽑아낸 데이터에 대해서는 어떻게 해야 각 field의 데이터를 추출해 낼 수 있는지에 대해서도 굉장히 많은 이해의 시간과 시행착오의 시간을 가져야 했습니다.
결국, 공식문서를 잘 읽어 보는게 중요하다는 점 간과하고, 덤빈 덕에 고생 꽤나 하였는데요.
당장, DB접근의 가장 기본인 CRUD 중 READ. 즉, 데이터 조회부터 하려들면, 부닥치게 되는 부분이니 꼭 먼저 언급하고 싶었습니다.
ORM을 통해 Queryset 객체를 뽑아낼 때, get 메소드를 쓰면, 메소드에 주어진 조건에 완벽하게 일치하는 조건의 데이터라인 1개를 찾으려 합니다. 그리고, 그 1개만을 담은 객체를 return하기 때문에, 각 데이터 column에 담긴 값에 접근하는 것도 filter()메소드보다는 편리하게 짜여 있습니다.
하지만, get() 메소드가 값 하나만을 담는다는 특성 때문에, 만약 method에 제공된 paramter 기준 여러 개의 결과 값을 가지고 있으면, 에러를 뱉습니다. 값이 없을 때에도 또한 에러를 뱉습니다.
오직 검색결과 단 1개의 filtering된 데이터 라인만을 갖는 경우에 한해서 get()메소드가 유효합니다.
따라서, 코딩 시 get()메소드를 반드시 써야 하는 경우라면 try / except 구문이 필요하게 됩니다. 내가 예상치 못한, 모종의 원인에 의해 결과값이 0개 또는 여러개를 가진 경우에는 에러를 뱉기 때문에 에러 회피를 위해서 입니다.
하지만, filter()메소드를 쓰면 값이 없으면 없는데로, 에러 없이 빈 queryset을 return합니다.
적어도 에러를 뱉는 것이 아니라, 결과 데이터를 표출하지 않는 방식으로 값을 돌려주기 때문에, 사이트가 에러에 빠져 404를 return한다거나 하는 일이 발생되지 않는다는 의미입니다.
이러저러한 상황을 보면, 왠만해선 fitler()메소드를 쓰는게 Read 측면에서는 유리하다는 사실을 알 수 있습니다.
하지만, filter()메소드는 각 데이터라인의 field값에 접근할 때엔, for문을 써서 여러개 들어있는 queryset객체 내의 각 데이터라인에 하나하나 접근하여 값을 추출해야 한다는 특징이 있습니다.
따라서, 값을 단 하나만 담고 있더라도, filer에 의해 돌려 받은 queryset에 담긴 값을 뽑아 내려면 for문을 필연적으로 사용하여야 한다는 특징이 있습니다. 반면, get에 의해 돌려 받은 queryset에 대해서는 곧바로 key값을 지정함으로써, value에 즉시 접근할 수 있게 됩니다.
일단, ORM 조회 관계된 get, filer에 대해서는 여기까지만 보고, 차회에 실제 코드를 살펴볼 때, 용례를 통해 다시 이야기 해보도록 하겠습니다.
다음, 포스팅에서 ORM에 관해서 계속 상술해 보겠습니다.
NPU(엔피유) 관세사무소
대표관세사 고장주
Tel) 031-986-7190
E-mail) sales@npucus.com
[NPU관세사무소 홈페이지] https://www.npucus.com/
[NPU관세사무소 프로모션 페이지] https://www.tradenpu.com/npu_cus/
[무역비지니스 인텔리전스 서비스 | TradeNPU] https://www.tradenpu.com
[파이썬 실용 예제. 무역과 공공데이터] https://pdatinmylife.tistory.com
Certified Customs Broker JangJu Goh
Executive Customs Broker @ NPU Customs Consulting
CEO @ JG TradePlus
sales@npucus.com
Trade Compliance / Customs clearance management at foreign company
Working experience of Air export freight forwarding
Data Visualization / Independent development of business automation application – copyright of JGPO_Manager, JG Data Center, AutoCC and etc.
B2B consignment & direct export/import, B2C Overseas Buying Office consulting
Alibaba.com B2B trade / taobao B2C trade / Amazon.com global selling etc. Online trade regulation consulting.
Import license / Quarantine
English communication available
[TradeNPU for partnership proposal - JGTP] https://www.tradenpu.com/jgtp/
'파이썬(Python) > TradeNPU' 카테고리의 다른 글
회원사 Item Introduction page 만들기 시리즈 V - ORM (2) (2) | 2024.11.13 |
---|---|
관세청 Open API 활용 프로젝트 #1 화물통관진행정보조회하기 (1) (4) | 2024.11.12 |
회원사 Item Introduction page 만들기 시리즈 IV - Django Templates (5) | 2024.11.08 |
회원사 Item Introduction page 만들기 시리즈 III - Django Template Tags (2) | 2024.11.07 |
회원사 Item Introduction page 만들기 시리즈 II - 로그인 구현 (5) | 2024.11.05 |