import psycopg2
from psycopg2 import errors
import logging
logger = logging.getLogger(__name__)
def safe_db_operation(pool, query, params=None):
"""안전한 데이터베이스 작업 패턴"""
conn = None
try:
conn = pool.getconn()
cursor = conn.cursor()
cursor.execute(query, params)
if query.strip().upper().startswith("SELECT"):
result = cursor.fetchall()
else:
conn.commit()
result = cursor.rowcount
return {"success": True, "data": result}
except errors.UniqueViolation as e:
# 중복 키 오류 (예: 이메일 중복)
if conn: conn.rollback()
logger.warning(f"중복 데이터: {e}")
return {"success": False, "error": "이미 존재하는 데이터입니다"}
except errors.ForeignKeyViolation as e:
# 외래 키 참조 오류
if conn: conn.rollback()
logger.warning(f"참조 무결성 위반: {e}")
return {"success": False, "error": "참조하는 데이터가 존재하지 않습니다"}
except errors.OperationalError as e:
# 연결 오류 (네트워크, 타임아웃 등)
logger.error(f"DB 연결 오류: {e}")
if conn:
pool.putconn(conn, close=True) # 불량 연결 폐기
conn = None
return {"success": False, "error": "데이터베이스 연결 오류가 발생했습니다"}
except Exception as e:
if conn: conn.rollback()
logger.error(f"예상치 못한 오류: {e}")
return {"success": False, "error": "처리 중 오류가 발생했습니다"}
finally:
if conn:
pool.putconn(conn)