SQLAlchemy 정리

Code_Builder·2025년 6월 30일

개인 쇼핑몰 토이 프로젝트를 개발하던 중, Gemini 파인튜닝을 활용한 챗봇 기능 구현을 진행
이 과정에서 Python(Flask FrameWork) 으로 뭔가 해봐야겠다라고 생각했고,
SQLAlchemy를 통해 이를 효과적으로 구현할 수 있음을 알게 되어 관련 내용을 정리하게 됨..

SQLAlchemy란?

Python에서 사용되는 SQL 툴킷 및 객체 관계 매핑(Object-Relational Mapping, ORM) 라이브러리

SQLAlchemy는 크게 두 가지 핵심 구성됨(필자는 두번째 방법 씀)

- SQL 툴킷 (Core): SQL을 파이썬 코드화

-> ex)

# MetaData 객체 생성: 데이터베이스 스키마 정의를 위한 컨테이너
# 이 객체에 테이블 정의들이 '등록'됩니다.
metadata = MetaData()

# --- 2. 스키마 정의 (테이블 생성) ---
# 'users' 테이블 정의
# Table 객체를 사용하여 S텍스트QL의 CREATE TABLE 문을 파이썬 코드로 표현
users_table = Table(
    "users", metadata,
    Column("id", Integer, primary_key=True, autoincrement=True), # ID 컬럼 (기본 키, 자동 증가)
    Column("name", String(50), nullable=False), # 이름 컬럼 (문자열, 필수)
    Column("email", String(100), unique=True, nullable=False) # 이메일 컬럼 (문자열, 고유, 필수)
)

- 객체 관계형 매퍼

-> ORM(데이터베이스 테이블을 파이썬 클래스로 직관적으로 표현)

필자는 뭔가 친근한 방법(?)인 객체 관계형 매퍼 방식으로 씀
ex)

  • 모델 생성 예시(실제 내 챗봇내의 소스코드중 일부)
class Order(Base):
    __tablename__ = "Order" //테이블명

    id = Column(UUID(as_uuid=True), primary_key=True)
    userId = Column(UUID(as_uuid=True), ForeignKey("User.id"))
    createdAt = Column(DateTime)
	...등등
    //관계 맵핑(관계 표시)
    user = relationship("User", back_populates="orders")

orders = (
    // 1. db.query(테이블_클래스_이름)
    //    테이블_클래스_이름: 데이터베이스 테이블에 매핑된 파이썬 클래스 (예: Order)
    db.query(Order) // 예시: Order 테이블에 매핑된 Order 클래스 사용

    // 2. .filter(테이블_클래스_이름.컬럼_속성 == 값)
    //    테이블_클래스_이름.컬럼_속성: 클래스의 속성으로 컬럼에 접근
    //    == : 동등 비교 연산자 (SQL의 WHERE 절과 동일)
    .filter(Order.userId == user_uuid) // 예시: Order 클래스의 userId 속성 사용

    // 3. .order_by(테이블_클래스_이름.컬럼_속성.desc() 또는 .asc())
    //    .desc(): 내림차순 정렬
    //    .asc(): 오름차순 정렬 (기본값이므로 생략 가능)
    .order_by(Order.createdAt.desc()) // 예시: Order 클래스의 createdAt 속성을 내림차순 정렬

    // 4. .all() 또는 .first() 등
    //    .all(): 쿼리 결과의 모든 행을 리스트로 반환
    //    .first(): 쿼리 결과의 첫 번째 행만 반환 (없으면 None)
    //    .one(): 쿼리 결과가 단 하나의 행일 때만 반환 (0개거나 2개 이상이면 에러)
    .all()
)

PRISMA(ORM)연결 설정(다른 DB도 가능)

load_dotenv() //env 파일에서 읽어옴

//REPLACE 안하면 나같은 경우 오류나서 씀 아니면 그냥 써도됨 
DATABASE_URL = os.getenv("당신의 DB URL").replace("postgres://", "postgresql://") 

//데이터베이스와의 실제 통신을 담당
engine = create_engine(당신의 DB URL, echo=True)
//db 세션 객체(=> 트랜잭션, SQL쿼리 생성 , 객체 상태관리 등등...)를 얻는 데 사용
SessionLocal = sessionmaker(bind=engine, autocommit=False, autoflush=False)

Base = declarative_base()

장단점

ORM 답게 쿼리작성 안해도 딸깍하면 쿼리 만들어주니 편한데...모르면 못씀.....,
복잡한(조인 등등)쿼리는 직접 작성하는게 더 편함


새로운 도구를 배우는게 쫌 재미있기도 하면서 신기하다..(JPA 와 또다른 ORM...)
챗봇 파인튜닝 개발 하면서 뭔가 더 해봐야겠다....

개발 중간에 도움 받은 곳:https://docs.sqlalchemy.org/en/14/orm/query.html#the-query-object

profile
사소한일에도 최선을 다하기

0개의 댓글