오늘은 영화 검색을 가능케하는 코드를 클래스를 활용하여 짜보자.
영화 검색: 제목, 장르, 배우 등 다양한 조건으로 영화를 검색할 수 있는 기능.
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()을 통해서 모두 담아준다.