1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Python】SQLAlchemy 入門〜実務で必ず使うところだけ最速で理解するガイド

1
Posted at

はじめに

Python の ORM といえば SQLAlchemy。
でも実際は「覚える範囲、広すぎ問題」があって、最初は絶対に迷う。

この記事では、最低限+実務レベルで絶対に使う部分だけ、未来の自分が読み返しても迷わない形で整理する。


SQLAlchemy は何ができる?

SQLAlchemy は「ORM+SQL ツールキット」の二刀流フレームワーク。

  • ORM(Python クラスで DB を扱う)
  • Core(生 SQL を Python から安全に書く)

FastAPI や Flask と組み合わせる場面では ほぼ ORM のみ で十分。
実務では ORM と Core をハイブリッドで使う場面もあるが、まずは ORM を理解すればOK。


基本構造:ORM の 4 コンポーネント(最重要)

SQLAlchemy ORM の最小構成は以下の 4 つ。

  • Base(ORM の親クラス)
  • Model(テーブル)
  • Engine(DB 接続)
  • Session(DB 操作用オブジェクト)

これを順番に見ていく。


Base(ORM の土台)

from sqlalchemy.orm import DeclarativeBase

class Base(DeclarativeBase):
    pass

すべてのモデルはこの Base を継承する。
Django で言う models.Model 的な存在。


Model(テーブル定義)

新しい SQLAlchemy の書き方「Mapped + mapped_column」を使うときれいになる。

from sqlalchemy.orm import Mapped, mapped_column
from sqlalchemy import String, Integer

class User(Base):
    __tablename__ = "users"

    id: Mapped[int] = mapped_column(primary_key=True)
    name: Mapped[str] = mapped_column(String(100))
    email: Mapped[str] = mapped_column(String(200), unique=True)

ポイント:

  • Python の型ヒント=そのまま DB 型推論に使える
  • Mapped[] で SQLAlchemy に「これは ORM カラムですよ」と教える
  • 実務ではほぼこの書き方一択

Engine(DB との接続管理)

from sqlalchemy import create_engine

engine = create_engine(
    "sqlite:///./app.db",
    echo=True,            # 実行された SQL をログに出す
)

実務では postgresql+psycopg:// をよく使う。


Session(DB の操作をする実体)

from sqlalchemy.orm import sessionmaker

SessionLocal = sessionmaker(
    bind=engine,
    autocommit=False,
    autoflush=False,
)

使うときは:

db = SessionLocal()

user = db.query(User).first()
print(user)

Session は「短命」で使う(FastAPI は1リクエスト1セッション)。


CRUD(実務の 90% はこれ)

Create

user = User(name="Test", email="test@example.com")
db.add(user)
db.commit()
db.refresh(user)

refresh() は INSERT 後に生成された id などを取得。


Read

user = db.query(User).filter(User.id == 1).first()

複数:

users = db.query(User).all()

Update

user = db.query(User).filter(User.id == 1).first()
user.name = "NewName"
db.commit()

Delete

db.delete(user)
db.commit()

リレーション(1対多・多対多)

これも実務必須。

User ←→ Post(1対多)

from sqlalchemy.orm import relationship
from sqlalchemy import ForeignKey

class User(Base):
    __tablename__ = "users"
    id: Mapped[int] = mapped_column(primary_key=True)
    posts: Mapped[list["Post"]] = relationship(back_populates="user")

class Post(Base):
    __tablename__ = "posts"
    id: Mapped[int] = mapped_column(primary_key=True)
    user_id: Mapped[int] = mapped_column(ForeignKey("users.id"))
    user: Mapped[User] = relationship(back_populates="posts")

SQLAlchemy のリレーションは「両方向」で書くと扱いやすい。


async SQLAlchemy(FastAPI の新標準)

FastAPI + SQLAlchemy は async が今の主流

from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import sessionmaker

engine = create_async_engine("sqlite+aiosqlite:///./test.db")

async_session = sessionmaker(
    engine, class_=AsyncSession, expire_on_commit=False
)

使用:

async with async_session() as session:
    result = await session.execute(select(User))
    users = result.scalars().all()

FastAPI との組み合わせ

def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

エンドポイント:

@app.get("/users")
def list_users(db: Session = Depends(get_db)):
    return db.query(User).all()

Clean Architecture での配置(実務レベル)

SQLAlchemy を Clean Architecture で使うなら:

/domain
    models/
    repositories/
    
/data
    sqlalchemy/
        models/
        repositories/
        session.py

ポイント:

  • domain は SQLAlchemy を知らない(import しない)
  • repositories が SQLAlchemy 実装を隠蔽する
  • data 層に Model / Session を閉じ込める

例:UserRepository

class UserRepositoryImpl(UserRepository):

    def __init__(self, session):
        self.session = session

    def find_by_id(self, user_id: int):
        return (
            self.session
            .query(UserModel)
            .filter(UserModel.id == user_id)
            .first()
        )

実務の “正しい SQLAlchemy の使い方” はまさにこれ。


Migration(Alembic)

SQLAlchemy を使うなら Alembic も自動的にセット。

初期化:

alembic init migrations

model → migration:

alembic revision --autogenerate -m "create user"
alembic upgrade head

実務では必須級。


はじめに

  1. Model 定義
  2. CRUD
  3. Relation
  4. Session の扱い
  5. async
  6. Migration(Alembic)
  7. Clean Architecture 組み込み

この順番が絶対に効率いい。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?