ORM이란
- ORM(Object-Relational Mapping)이란 DB의 테이블을 프로그래밍 언어의 class로, 테이블의 row들을 객체(instance)로 매핑하는 기술을 의미하며, 이를 통해 직접 SQL 문을 작성하지 않고도 DB와 상호작용할 수 있습니다.
- 예시로 User 테이블을 python class로 작성하면 아래와 같습니다.
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String)
age = Column(Integer)
- ORM은 기본적으로 객체 지향적인 방식으로 데이터를 다루게 해줍니다. 또한 SQL이 아니라 python backend를 사용한다면 python code로 작성이 가능하게 해주기때문에, 일관성이 유지되며 코드로 통합되므로 유지 보수도 용이합니다.
- 또한, DB와 독립적이기때문에 다양한 DB 엔진(MySQL, PostgreSQL)을 사용하기에 적합합니다. 즉, DB 엔진이 바뀌어도 크게 문제되지 않습니다.
- 하지만 SQLAlchemy같은 라이브러리를 통해 SQL문이 자동 생성되는 방식이기 때문에 복잡한 쿼리는 최적화가 잘 되어있지 않을 수 있고, 그에 따라 비효율적일 수 있습니다.
SQLAlchemy, Pydantic
- SQLAlchemy는 python backend를 사용한다면 자주 사용되는 라이브러리로, python class로 DB 테이블 정보를 매핑할 수 있습니다.
- Pydantic은 FastAPI를 사용한다면 자연스럽게 사용하게 되는 라이브러리로, 데이터 검증과 직렬화를 수행할 수 있습니다.
- 둘을 함께 사용하는 방식은 아래와 같습니다.
- Pydantic을 사용해 요청 데이터 검증
- SQLAlchemy를 사용해 DB에 데이터 저장
- Backend 라이브러리를 통해 최종 결과 반환
- 그 예시는 아래와 같습니다.
- ORM 라이브러리, 그리고 Pydantic을 함께 사용함으로써, DB를 코드로 통합하여 관리할 수 있습니다.
from fastapi import FastAPI, Depends, HTTPException
from sqlalchemy.orm import Session
from pydantic import BaseModel
from .database import engine, SessionLocal, Base
from sqlalchemy import Column, Integer, String
app = FastAPI()
Base.metadata.create_all(bind=engine)
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True)
name = Column(String, index=True)
age = Column(Integer)
class UserCreate(BaseModel):
name: str
age: int
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
@app.post("/users/", response_model=UserCreate)
def create_user(user: UserCreate, db: Session = Depends(get_db)):
db_user = User(name=user.name, age=user.age)
db.add(db_user)
db.commit()
db.refresh(db_user)
return db_user