SQLAlchemy는 Python에서 작업하기 위한 SQL 툴킷과 객체 관계형 매퍼를 제공해준다. SQLALchemy는 크게 ORM(Object Relational Mapper)과 코어로 나눌 수 있다. 코어에는 광범위한 SQL 및 DB 통합 및 설명 서비스가 포함되어 있다.
# SQLite 사용 예시
from sqlalchemy import create_engine
engine = create_engine("sqlite+pysqlite:///:memory:", echo=True) # DB: sqlite, DBAPI: pysqlite, /:memory : using an in-memory-only database.
from sqlalchemy import text
with engine.connect() as conn:
conn.excute(text("CREATE TABLE example (x int, y int)"))
conn.commit() # 커밋하지 않으면 롤백된다.
from sqlalchemy.orm import Session
# Session을 생성하는 패턴은 여러 가지가 존재하고 아래 예시는 가장 기본적인 방식이다
stmt = text("SELECT x, y FROM some_table WHERE y > :y ORDER BY x, y")
with Session(engine) as session:
result = session.execute(stmt, {"y": 6})
for row in result:
print(f"x: {row.x} y: {row.y}")
# session.commit() # 만약 변경 사항이 있을 때 커밋하는 것을 잊지말자
from sqlalchemy import MetaData
meatadata_obj = MetaData()
예시 - 유저 테이블
from sqlalchemy import Table, Column, Integer, String
user_table = Table(
"user_account",
metadata_obj,
Column("id", Integer, primary_key=True),
Column("name", String(30)),
Column("fullname", String),
)
user_table.c.name # Column('name', String(length=30), table=<user_account>)
user_table.c.keys() # ['id', 'name', 'fullname']
user_table.primary_key # pk에 대한 속성 - PrimaryKeyConstraint(Column('id', Integer(), table=<user_account>, primary_key=True, nullable=False))
from sqlalchemy import ForeignKey
address_table = Table(
"address",
metadata_obj,
Column("id", Integer, primary_key=True),
Column("user_id", ForeignKey("user_account.id"), nullable=False),
Column("email_address", String, nullable=False),
)
metadata_obj.create_all(engine)
from sqlalchemy.orm import DeclarativeBase
class Base(DeclarativeBase):
pass
Base.metadata # MetaData()
from typing import List
from typing import Optional
from sqlalchemy.orm import Mapped
from sqlalchemy.orm import mapped_column
from sqlalchemy.orm import relationship
class User(Base):
__tablename__ = "user_account"
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String(30))
fullname: Mapped[Optional[str]]
addresses: Mapped[List["Address"]] = relationship(back_populates="user")
def __repr__(self) -> str:
return f"User(id={self.id!r}, name={self.name!r}, fullname={self.fullname!r})"
class Address(Base):
__tablename__ = "address"
id: Mapped[int] = mapped_column(primary_key=True)
email_address: Mapped[str]
user_id = mapped_column(ForeignKey("user_account.id"))
user: Mapped[User] = relationship(back_populates="addresses")
def __repr__(self) -> str:
return f"Address(id={self.id!r}, email_address={self.email_address!r})"
Base.metadata.create_all(engine)
some_table = Table("some_table", metadata_obj, autoload_with=engine)