본문 바로가기

카테고리 없음

dvdrental 데이터로 PSQL 연습

오늘은 영화 검색을 가능케하는 코드를 클래스를 활용하여 짜보자. 

 

영화 검색: 제목, 장르, 배우 등 다양한 조건으로 영화를 검색할 수 있는 기능.

 

 

 

 

import psycopg2
from dotenv import load_dotenv
import os

#상속, 정보보호


load_dotenv()   #.env 파일 내용을 환경 변수로 로드함.

#환경변수 읽어옴.
db_name = os.getenv('DB_NAME')
db_user = os.getenv('DB_USER')
db_password = os.getenv('DB_PASSWORD')
db_host = os.getenv('DB_HOST')
db_port = os.getenv('DB_PORT')

 

처음에 .env 파일을 환경변수로 하여 필요한 변수들을 불러온다. 

 

나의 .env 파일엔 

DB_NAME='testdb'
DB_USER='postgres'
DB_PASSWORD='----'
DB_HOST='localhost'
DB_PORT='----'

뭐 이런식으로 저 변수들에 대해서 정의를 해놓았다. 

 

 

그 다음 DB에 접속하기 위한 기본클래스를 만들자. 

 

class Main:
    def __init__(self):
        self.conn_params = {
            'dbname': db_name,
            'user': db_user,
            'password': db_password,
            'host': db_host,
            'port': db_port
            }
        
        self.conn = None
        self.connect()

    def connect(self):
        #DB에 연결. #self.conn은 클래스의 __init__메서드에서 생성된 db연결객체
        try:
            self.conn = psycopg2.connect(**self.conn_params)
            #**의 주요 사용 사례
            #함수 호출에서의 사용: **는 딕셔너리를 함수의 키워드 인자로 분해하여 전달할 때 사용됨. 
            #함수에 여러 키워드 인자를 한 번에 전달가능.
            print("데이터베이스에 성공적으로 연결되었습니다.")
        except psycopg2.Error as e:
            print(f"데이터베이스 연결 중 오류가 발생했습니다: {e}")

 

 

params 안에는 db에 접속할 때 필요한 모든 정보들이 들어있다. 

self.conn이 __init__단계에서는 connect 함수를 통해 내 DB로 들어가는 무기가 된다. 

DB로 들어갈 때, **을 통해 필요한 5개의 정보를 한 번에 전달할 수 있다.

 

 

 

 

 

class Search(Main):
    
    def by_genre(self):
        print("검색 가능 키워드 : Action Animation Children Classics Comedy Documentary Drama Family Foreign Games Horror Music New Sci-Fi Sports Travel")
        keyword = str(input("검색할 키워드를 입력해주세요 :"))
        keyword = keyword.capitalize()

        query = f"""select c.name, f.title
                        from category c 
                        inner join film_category fc using (category_id)
                        inner join film f using (film_id)
                        where c.name ILIKE '%{keyword}%'
                        group by c.name, f.title ;"""
        
        try:
            with self.conn.cursor() as cur:
                cur.execute(query)
            #execute 안에 ' 하나도 신경써줘야함.
                results = cur.fetchall()
                if results:
                    for result in results:
                        print(result)
                else:
                    print("검색 결과가 없습니다.")
        except Exception as e:
            print(f"오류가 발생했습니다: {e}")
    
    def by_actor(self):
        keyword = str(input("검색할 키워드를 입력해주세요(first name or last name) :"))
        keyword = keyword.capitalize()

        query = f"""SELECT a.actor_id, f.title, a.first_name, a.last_name 
                FROM actor a 
                INNER JOIN film_actor fa USING (actor_id)
                INNER JOIN film f USING (film_id)
                WHERE a.first_name = '{keyword}'
                OR a.last_name = '{keyword}'
                ORDER BY a.actor_id, f.title DESC;"""
        try:
            with self.conn.cursor() as cur:
                cur.execute(query)
                results = cur.fetchall()
                if results:
                    for result in results:
                        print(result)
                else:
                    print("검색 결과가 없습니다.")
        except Exception as e:
            print(f"오류가 발생했습니다: {e}")
        
    def by_title(self):
        keyword = str(input("검색할 키워드를 입력해주세요(title keyword 입력) :"))
        keyword = keyword.capitalize()

        query = f"""SELECT f.title, f.description, f.release_year
                    FROM film f
                    WHERE f.title ILIKE '%{keyword}%';"""
        try:
            with self.conn.cursor() as cur:
                cur.execute(query)
                results = cur.fetchall()
                if results:
                    for result in results:
                        print(result)
                else:
                    print("검색 결과가 없습니다.")
        except Exception as e:
            print(f"오류가 발생했습니다: {e}")


first_search = Search()

first_search.by_genre()
first_search.by_actor()
first_search.by_title()

 

query 안에있는 코드는 psql로 들어갔을 때 필요한 코드를 넣는다. 

 

쿼리를 짤 때,이어줘야 할 경우는 inner join을 통해서 테이블을 이어주고

검색을 할땐 where 원하는table ILIKE '%keyword%'를 해주면 저 키워드가 포함되었다면 다 검색해준다. 

마지막엔 group by나 order by를 통해서 정리해줄 수 있다. 

 

 

with self.conn.cursor() as cur:
                cur.execute(query)
 

커서를 열어서 내 쿼리를 넣어주고. 

 

결과는 cur.fetchall()을 통해서 모두 담아준다.