본문 바로가기
Backend MLOps/Database

Fastapi docs 무작정 따라하기 ORM 편 - 2

by SteadyForDeep 2022. 6. 6.
반응형

Create the Pydantic models

이전 포스팅에서 SQLAlchemy의 models를 구성하고 제작하는 방식을 알아보았다.
그리고 언급한 부분이 pydantic의 model과 sqlalchemy의 model이 다르므로
혼동해서는 안된다는 내용이었다.

pydantic은 데이터 검증을 위해 사용하는 툴로
타입 힌트를 이용해 데이터의 타입을 명시하고 그에 맞지 않는 데이터가 발견되면
에러를 발생시켜 데이터의 형태를 강제하는 용도로 사용한다.
api를 이용한 io 테스크가 많은 백엔드 작업시에 굉장히 유용한 툴이다.
io 작업에서는 직렬화된 데이터를 주고 받는 작업이 대부분인데
pydantic은 이 직렬화된 데이터를 파싱해주는 툴이기 때문이다.
그래서 만약 파싱이 불가능한 데이터는 에러를 발생시키고
파싱이 가능하다면 주어진 힌트로 파싱을 하는 방식으로 동작한다.

CRUD 작업을 수행할 때
요청과 처리의 데이터 폼이 맞지 않아 발생할 수 있는 문제들을
미연에 방지해 주는 효과가 있어 fastapi에서 사용하고 있다.

sql_app/schemas.py파일을 작성해 보자.
계속 언급하듯 sqlalchemy의 model과 헷갈리는 것을 방지하기 위해
pydantic model 들은 schema라는 이름으로 부르기로 한다.

우선 BaseModel을 상속받아 schema를 만들어준다.
이렇게 하면 schema에 맞지 않는 데이터들은 파싱이 불가능하므로 에러가 발생하고
모든 데이터들이 동일한 attribute들을 가지게 된다.
그리고 생성자도 일단 선언해 준다.

모델에 해당하는 Userhashed_password를 가지고 있었지만
스키마에 해당하는 UserBase는 그렇지 않다.
따라서 User의 정보를 쓰는 것이 아니라 읽는 상황에서
비밀번호를 읽을 수 없도록 스키마로 검증을 할 수 있다.
이런식으로 보안을 위해 사용하는 것이 가능하다고 소개하고 있다.

Config에는 이 모델이 ORM을 위한 모델이라는 것을 명시해 준다.
이 부분을 명시함으로 dict의 key-value로 접근 가능하던 부분을 attribute로 접근할 수 있게 해주고
lazy loading으로 처리되는 부분에서 모델과 스키마의 충돌이 일어나지 않도록 해준다.
sqlalchemy는 lazy loading 방식으로 처리되는데 꼭 필요한 순간이 아니면
DB세션과 소통하지 않는 다는 말이다. 그래서 relationship으로 연결해 둔 테이블은
어떤 시점에서는 아직 불러와 지지 않은 상태로 남아있게되고
그때 스키마와 모델간의 차이가 발생해 충돌이 생길 수 있다.

사실 스키마 부분은 CRUD와 함께 보는 것이 가장 이해가 빠르다.
바로 CRUD 구현부터 API까지 달려보도록 하자.

CRUD util

CRUD는 Create, Read, Update and Delete의 약자다.
생성, 조회, 수정, 삭제 라고도 한다.
sql_app/crud.py 파일에서 구현해보자.

직접적으로 어떻게 사용할 수 있는지 테스트 해보면

쿼리를 보기 위해서 로거를 활성화 하고
models.Basedatabase.py파일에서 만들었던 declarative_base()의 모든 모델을 생성해 준다.

create 쿼리가 전송되면서 테이블을 만들었다.

여기서 테이블에 내용을 입력하게 되는데

플레이스홀더 ? 에 적절한 파라미터를 넣으면서 쿼리를 생성하고 커밋한 것을 볼 수 있다.

마지막으로 이 query 라는 메소드에서는 SELECT를 수행하는데

위와 같이 수행된 것을 볼 수 있다.

파라미터만 적절하게 잘 넣어주면

원활하게 실행되는 것을 볼 수 있다.
저기서 "user.email" 이런식으로 표현한 부분이 있는데 이 부분을 요청으로 부터 파싱하여
pydantic으로 검사 한 후 스키마에 맞는 형태로 받아오는 작업을 해주면 crud api가 완성된다.

잘 보면 create에서 UserCreate 스키마를 사용하는 것을 볼 수 있는데
왜 똑같은걸 굳이 다른 이름으로 쓰냐 하면
crud 네가지 경우에서 서로 다른 데이터를 주고 받는 상황을 생각한 것이다.
그래서 필요한 메소드에 맞춘 필요한 스키마를 정한 후 사용하도록 나누어서 쓰는 것이다.

 
반응형

댓글