나무모에 미러 (일반/어두운 화면)
최근 수정 시각 : 2025-05-15 20:23:27

SQLAlchemy

SQLAlchemy
<colbgcolor=#fff,#1f2023><colcolor=#3EB049> 창시자 Michael Bayer[1]
출시일 2006년 02월 14일[2]
최신 버전 v2.0.41#
유형 데이터베이스 ORM[3]
사용 언어 Python
공식 웹사이트 공식 사이트 공식 문서 깃허브
1. 개요2. 특성3. 구성 요소
3.1. Core3.2. ORM
4. 사용 방법
4.1. 1.x 스타일4.2. 2.0 스타일


1. 개요

#!syntax sh
# SQLAlchemy 설치 (pip)
pip install SQLAlchemy

# 비동기 extra를 함께 설치하는 경우
pip install "SQLAlchemy[asyncio]"

SQLAlchemy는 Python데이터베이스 라이브러리로, SQL데이터베이스 작업을 파이썬 객체를 통해 조작할 수 있게 한다. 단순한 데이터베이스 연결부터 복잡한 객체-관계 매핑까지 다양한 수준의 추상화를 제공한다.

Django 프레임워크에 내장된 Django ORM과 비교했을 때, SQLAlchemy는 프레임워크에 종속되지 않는 독립적인 라이브러리로서, 더 낮은 수준의 데이터베이스 제어와 높은 유연성을 제공한다. Django ORM이 웹 프레임워크의 일부로 통합되어 있어 빠른 개발에 유리하다면, SQLAlchemy는 어떤 파이썬 프로젝트에서도 사용할 수 있으며, 복잡하거나 특수한 데이터베이스 요구사항에 더 잘 대응할 수 있다.

2. 특성

3. 구성 요소

3.1. Core

SQLAlchemy Core는 데이터베이스 스키마를 표현하고 쿼리 생성 및 실행하는 저수준의 기능을 제공한다. 데이터베이스 연결 풀, 트랜잭션 관리, 스키마 정의[6], SQL 표현식 구성 등의 기능을 포함한다. ORM을 사용하지 않고 순수하게 쿼리를 Python 코드로 작성하고 실행해야 할 때 유용하다.

3.2. ORM

SQLAlchemy ORM은 파이썬 클래스를 데이터베이스 테이블과 매핑하여 객체 지향적인 방식으로 데이터베이스를 조작할 수 있게 해준다. 데이터베이스의 레코드를 Python 객체로, 필드를 객체의 속성으로 매핑한다. 이를 통해 쿼리를 직접 작성하는 대신 Python 객체를 다루듯이 데이터를 조회, 생성, 수정, 삭제할 수 있다. 또한 복잡한 관계[7] 매핑 및 로딩 전략 설정[8] 등 강력한 기능을 제공한다.

4. 사용 방법

4.1. 1.x 스타일

1.x 버전에서는 주로 declarative_base를 사용하여 모델 클래스의 베이스를 만들고, 클래스 속성으로 Column 객체를 직접 할당하는 방식으로 모델을 정의했다.
#!syntax python
from sqlalchemy import Column, Float, Integer, String
from sqlalchemy.orm import declarative_base

Base = declarative_base()


class User(Base):
    __tablename__ = "users"

    id = Column(Integer, primary_key=True)
    name = Column(String, nullable=False)
    value = Column(Float, default=None, nullable=True)

데이터를 조회할 때는 주로 session.query를 사용했다.
#!syntax python
# User 모델이 정의되어 있고, users 테이블이 생성되어 있다고 가정
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

engine = create_engine("sqlite:///:memory:")
Session = sessionmaker(bind=engine)

with Session() as session:
    for user in session.query(User):
        print(user)

4.2. 2.0 스타일

2.0에서는 Python의 타입 힌트, Mapped, mapped_column을 활용하는 새로운 선언적 매핑 스타일을 도입했다.
#!syntax python
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, sessionmaker


class Base(DeclarativeBase):
    pass


class User(Base):
    __tablename__ = "users"

    id: Mapped[int] = mapped_column(primary_key=True)
    name: Mapped[str]
    value: Mapped[float | None] = mapped_column(default=None)

데이터를 조회할 때는 select와 session.scalars를 사용하여 ORM 객체를 조회한다.[9]
#!syntax python
# User 모델이 정의되어 있고, users 테이블이 생성되어 있다고 가정
from sqlalchemy import create_engine, select
from sqlalchemy.orm import sessionmaker

engine = create_engine("sqlite:///:memory:")
Session = sessionmaker(bind=engine)

with Session() as session:
    for user in session.scalars(select(User)):
        print(user)


2.0문법을 사용할 경우 pyright와 같은 정적 분석기가 ORM 객체의 각 속성에 대한 타입을 정확하게 추론하므로, IDE를 사용할 때 생산성이 크게 향상된다.[10][11]
[1] 현재는 커뮤니티 주도로 개발이 이뤄지고 있다.[2] pypi 릴리즈 기준[3] Object-Relational Mapper[4] Dialect라는 객체로 각 데이터베이스에 대한 프로토콜을 구현했다.[5] 현존하는 거의 모든 데이터베이스에 대해 지원한다.[6] 테이블, 컬럼 등[7] 일대일, 일대다, 다대다[8] selectinload, joinedload[9] execute가 반환하는 Result객체의 scalars 메소드를 호출한 것과 동일하다.[10] User.id를 예시로, 모델 클래스의 속성은 InstrumentedAttribute\[int\]로 추론하고, 조회한 모델 객체의 속성은 int로 추론한다.[11] 1.4버전 사용자를 위한 스텁 라이브러리가 있지만 불완전하며, 2.0출시 이후 개발이 중단되었다.