diff --git a/app/crud/movie.py b/app/crud/movie.py index df40559..7f30250 100644 --- a/app/crud/movie.py +++ b/app/crud/movie.py @@ -1,15 +1,44 @@ from sqlalchemy.orm import Session from app.models.movie import Movie from sqlalchemy.exc import SQLAlchemyError +from typing import Dict import logging logger = logging.getLogger(__name__) -def search_movies_by_name(db: Session, keyword: str): +def search_movies_by_name(db: Session, keyword: str, skip: int = 0, limit: int = 10) -> Dict: try: - movies = db.query(Movie).filter(Movie.title.ilike(f"%{keyword}%")).all() - return movies + total_items = db.query(Movie).filter(Movie.title.ilike(f"%{keyword}%")).count() + movies = db.query(Movie).filter(Movie.title.ilike(f"%{keyword}%")).offset(skip).limit(limit).all() + total_pages = (total_items + limit - 1) // limit # 올림 처리 + return { + "total_pages": total_pages, + "total_items": total_items, + "movies": movies + } except SQLAlchemyError as e: logger.error(f"Database error occurred: {e}") - return [] + return { + "total_pages": 0, + "total_items": 0, + "movies": [] + } + +def get_movies_list(db: Session, skip: int = 0, limit: int = 10) -> Dict: + try: + total_items = db.query(Movie).count() + movies = db.query(Movie).offset(skip).limit(limit).all() + total_pages = (total_items + limit - 1) // limit # 올림 처리 + return { + "total_pages": total_pages, + "total_items": total_items, + "movies": movies + } + except SQLAlchemyError as e: + logger.error(f"Database error occurred: {e}") + return { + "total_pages": 0, + "total_items": 0, + "movies": [] + } \ No newline at end of file diff --git a/app/routers/movie.py b/app/routers/movie.py index fab5e81..4712a5f 100644 --- a/app/routers/movie.py +++ b/app/routers/movie.py @@ -1,16 +1,54 @@ from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.orm import Session -from app.crud.movie import search_movies_by_name +from app.crud.movie import search_movies_by_name, get_movies_list from app.database import get_db +from typing import Dict +from app.schemas.movie import MovieSchema, MovieSummarySchema router = APIRouter() -@router.get("/search-movie/") -def search_movie(title: str, db: Session = Depends(get_db)): - # 데이터베이스에서 부분 검색 - searched_movies = search_movies_by_name(db, keyword=title) - - if not searched_movies: +@router.get("/", response_model=Dict) +def get_movies(page: int = 1, item: int = 10, detail: str = 'n', db: Session = Depends(get_db)): + if page < 1 or item < 1: + raise HTTPException(status_code=400, detail="페이지 번호와 항목 수는 1 이상이어야 합니다.") + + skip = (page - 1) * item + result = get_movies_list(db, skip=skip, limit=item) + + if not result["movies"]: raise HTTPException(status_code=404, detail="영화를 찾을 수 없습니다.") - return searched_movies + movies = [ + MovieSummarySchema.model_validate(movie) if detail == 'n' else MovieSchema.model_validate(movie) + for movie in result["movies"] + ] + + return { + "total_pages": result["total_pages"], + "total_items": result["total_items"], + "page": page, + "movies": movies + } + +@router.get("/search", response_model=Dict) +def search_movie(title: str, page: int = 1, item: int = 10, detail: str = 'n', db: Session = Depends(get_db)): + if page < 1 or item < 1: + raise HTTPException(status_code=400, detail="페이지 번호와 항목 수는 1 이상이어야 합니다.") + + skip = (page - 1) * item + result = search_movies_by_name(db, keyword=title, skip=skip, limit=item) + + if not result["movies"]: + raise HTTPException(status_code=404, detail="해당 키워드로 영화를 찾을 수 없습니다.") + + movies = [ + MovieSummarySchema.model_validate(movie) if detail == 'n' else MovieSchema.model_validate(movie) + for movie in result["movies"] + ] + + return { + "total_pages": result["total_pages"], + "total_items": result["total_items"], + "page": page, + "movies": movies + } \ No newline at end of file diff --git a/app/schemas/movie.py b/app/schemas/movie.py index 161dcf0..199f4d4 100644 --- a/app/schemas/movie.py +++ b/app/schemas/movie.py @@ -4,6 +4,26 @@ from typing import Optional, List from datetime import date, datetime +class MovieSummarySchema(BaseModel): + id: int + title: str + poster_path: Optional[str] = None + vote_average: Optional[float] = None + director: Optional[str] = None + release_date: Optional[date] = None + + @field_validator('release_date', mode='before') + def parse_release_date(cls, value): + if value and isinstance(value, str): + try: + return datetime.strptime(value, "%Y-%m-%d").date() + except ValueError: + return None + return value + + class Config: + from_attributes = True + class MovieSchema(BaseModel): id: int title: str