SQLAlchemy 입문

OneDayDev·2023년 4월 6일
0

SQLAlchemy

Overview

참고:SQLAlchemy.org

SQLAlchemy는 Python에서 작업하기 위한 SQL 툴킷과 객체 관계형 매퍼를 제공해준다. SQLALchemy는 크게 ORM(Object Relational Mapper)과 코어로 나눌 수 있다. 코어에는 광범위한 SQL 및 DB 통합 및 설명 서비스가 포함되어 있다.

Engine

  • SQLAlchemy의 시작
  • 특정 데이터베이스에 대한 연결의 중앙 역할을 하며 데이터베이스 연결을 위한 connection pool이라는 보유 공간을 모두 제공합니다.
  • 일반적으로 특정 DB 서버에 대해 한 번만 생성된 글로벌 객체이며, URL을 사용해 구성된다.
# 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.

Engine 연결 예시

엔진 사용자 관점에서의 연결 예시

from sqlalchemy import text

with engine.connect() as conn:
	conn.excute(text("CREATE TABLE example (x int, y int)"))
	conn.commit() # 커밋하지 않으면 롤백된다.

ORM 세션으로 실행 예시

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() # 만약 변경 사항이 있을 때 커밋하는 것을 잊지말자

MetaData

  • SQLAlchemy Core와 ORM의 핵심 요소는 SQL 쿼리를 구성 가능하게 하는 SQL Expression Language이다.
  • 이러한 쿼리의 기초는 테이블의 열과 같은 데이터베이스 개념을 나타내는 파이썬 객체이다.
  • 이 객체들을 DB MetaData로 보면 된다.

테이블 객체로 메타데이터 설정하기

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),
)

Table 구성 요소

  • Table - DB Table을 나타내고 MetaData에 할당한다
  • Column - DB Table의 Column을 나타내고 Table 객체에 할당한다. Table.c로 호출
user_table.c.name # Column('name', String(length=30), table=<user_account>)
user_table.c.keys() # ['id', 'name', 'fullname']
  • Integer, String : SQL datatypes.

간단한 제약 선언 예시

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),
)

Emitting DDL

metadata_obj.create_all(engine)

ORM 선언 양식을 사용하여 테이블 메타데이터 정의

선언적 기반 구축

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})"

emitting

Base.metadata.create_all(engine)

Table Reflection

  • Table Reflection은 생성 과정을 가르킨다.
  • 하지만, 기존 데이터베이스에서 시작하여 해당 데이터베이스 내의 스키마를 나타내기 위해 파이썬 데이터 구조를 생성하는 이 두 단계를 역으로 수행한다.
some_table = Table("some_table", metadata_obj, autoload_with=engine)

Data 다루기

INSERT
SELECT
UPDATE&DELETE

profile
안녕하세요.

0개의 댓글