mcpField
P
python-database-ops

python-database-ops

github.com/0xdarkmatterデータ・データベース7853 回インストール2 週間前に更新
リポジトリ

python-database-ops について

SQLAlchemy 2.0を使うPython開発者向けのデータベース実践スキルです。同期・非同期の利用法、クエリ、FastAPIのセッション連携を扱います。

主な機能

  1. 01SQLAlchemy 2.0のORMパターン
  2. 02非同期セッションとエンジン
  3. 03リレーションとクエリ例
  4. 04FastAPIのセッション依存関係
  5. 05マイグレーションとプーリングのガイド

活用シーン

  1. 01型付きSQLAlchemyモデルの実装
  2. 02非同期データベースアクセスの構築
  3. 03一般的なクエリや結合の記述
  4. 04FastAPIでのDBセッション設定

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/0xdarkmatter/claude-mods --skill python-database-ops

インストール後、Claude Code で/python-database-opsを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

assets/
alembic.ini.template
references/
connection-pooling.md
migrations.md
sqlalchemy-async.md
transactions.md
scripts/
.gitkeep

詳細

Python データベースのパターン

SQLAlchemy 2.0 とデータベースのベストプラクティスです。

SQLAlchemy 2.0 の基本

from sqlalchemy import create_engine, select
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session

class Base(DeclarativeBase):
    pass

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(255), unique=True)
    is_active: Mapped[bool] = mapped_column(default=True)

# Create engine and tables
engine = create_engine("postgresql://user:pass@localhost/db")
Base.metadata.create_all(engine)

# Query with 2.0 style
with Session(engine) as session:
    stmt = select(User).where(User.is_active == True)
    users = session.execute(stmt).scalars().all()

非同期 SQLAlchemy

from sqlalchemy.ext.asyncio import (
    AsyncSession,
    async_sessionmaker,
    create_async_engine,
)
from sqlalchemy import select

# Async engine
engine = create_async_engine(
    "postgresql+asyncpg://user:pass@localhost/db",
    echo=False,
    pool_size=5,
    max_overflow=10,
)

# Session factory
async_session = async_sessionmaker(engine, expire_on_commit=False)

# Usage
async with async_session() as session:
    result = await session.execute(select(User).where(User.id == 1))
    user = result.scalar_one_or_none()

モデルのリレーションシップ

from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship, Mapped, mapped_column

class User(Base):
    __tablename__ = "users"

    id: Mapped[int] = mapped_column(primary_key=True)
    name: Mapped[str]

    # One-to-many
    posts: Mapped[list["Post"]] = relationship(back_populates="author")

class Post(Base):
    __tablename__ = "posts"

    id: Mapped[int] = mapped_column(primary_key=True)
    title: Mapped[str]
    author_id: Mapped[int] = mapped_column(ForeignKey("users.id"))

    # Many-to-one
    author: Mapped["User"] = relationship(back_populates="posts")

一般的なクエリパターン

from sqlalchemy import select, and_, or_, func

# Basic select
stmt = select(User).where(User.is_active == True)

# Multiple conditions
stmt = select(User).where(
    and_(
        User.is_active == True,
        User.age >= 18
    )
)

# OR conditions
stmt = select(User).where(
    or_(User.role == "admin", User.role == "moderator")
)

# Ordering and limiting
stmt = select(User).order_by(User.created_at.desc()).limit(10)

# Aggregates
stmt = select(func.count(User.id)).where(User.is_active == True)

# Joins
stmt = select(User, Post).join(Post, User.id == Post.author_id)

# Eager loading
from sqlalchemy.orm import selectinload
stmt = select(User).options(selectinload(User.posts))

FastAPI との統合

from fastapi import Depends, FastAPI
from sqlalchemy.ext.asyncio import AsyncSession
from typing import Annotated

async def get_db() -> AsyncGenerator[AsyncSession, None]:
    async with async_session() as session:
        yield session

DB = Annotated[AsyncSession, Depends(get_db)]

@app.get("/users/{user_id}")
async def get_user(user_id: int, db: DB):
    result = await db.execute(select(User).where(User.id == user_id))
    user = result.scalar_one_or_none()
    if not user:
        raise HTTPException(status_code=404)
    return user

クイックリファレンス

操作SQLAlchemy 2.0 の書き方
すべて選択select(User)
フィルター.where(User.id == 1)
最初の結果.scalar_one_or_none()
すべて取得.scalars().all()
件数select(func.count(User.id))
結合.join(Post)
イーガーロード.options(selectinload(User.posts))

追加リソース

  • ./references/sqlalchemy-async.md - 非同期パターン、セッション管理
  • ./references/connection-pooling.md - プール設定、ヘルスチェック
  • ./references/transactions.md - トランザクションパターン、分離レベル
  • ./references/migrations.md - Alembic のセットアップ、マイグレーション戦略

アセット

  • ./assets/alembic.ini.template - Alembic 設定テンプレート

関連項目

前提条件:

  • python-typing-ops - マップ型とアノテーション
  • python-async-ops - 非同期データベースセッション

関連スキル:

  • python-fastapi-ops - DB セッションの依存性注入
  • python-pytest-ops - データベースのフィクスチャとテスト

コメント