0Pricing
Python Academy · レッスン

非同期エンドポイントとデータベース連携

非同期のルートハンドラーを記述し、SQLAlchemy でデータベースに接続します。

「非同期エンドポイントとデータベース連携」はCoddyKit上の無料Python Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはPython Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Python Academyコースには全4レッスンが含まれています。

async def によるエンドポイント

ブロッキングしないI/Oには async def でルートハンドラーを宣言します。CPU負荷の高い処理やブロッキング処理には def を使います(FastAPIはそれらをスレッドプールで実行します)。

from fastapi import FastAPI
import asyncio
app = FastAPI()

@app.get("/slow")
async def slow():
    await asyncio.sleep(1)   # non-blocking
    return {"done": True}

PostgreSQL用asyncpg

asyncpg は高速な非同期PostgreSQLドライバーです。複数のリクエストで共有するコネクションプールを使用します。

# pip install asyncpg
import asyncpg, asyncio

async def main():
    pool = await asyncpg.create_pool("postgresql://user:pass@host/db")
    async with pool.acquire() as conn:
        rows = await conn.fetch("SELECT id, name FROM users")
    await pool.close()
    return rows

SQLAlchemyの非同期処理

SQLAlchemy 1.4+ と async_sessionmaker を使うと、非同期ORMを利用できます。AsyncSession をFastAPIの依存関係として使用します。

# pip install sqlalchemy aiosqlite
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession, async_sessionmaker

engine = create_async_engine("sqlite+aiosqlite:///db.sqlite")
AsyncSessionLocal = async_sessionmaker(engine, expire_on_commit=False)

async def get_db():
    async with AsyncSessionLocal() as session:
        yield session

データベース依存関係

FastAPIの依存関係からセッションを yield すると、リクエストの完了後にコミットして閉じることができます。

from fastapi import Depends, FastAPI
from sqlalchemy.ext.asyncio import AsyncSession
app = FastAPI()

async def get_db():
    async with AsyncSessionLocal() as session:
        yield session

@app.get("/users")
async def get_users(db: AsyncSession = Depends(get_db)):
    result = await db.execute(select(User))
    return result.scalars().all()

SQLAlchemy ORMモデル

DeclarativeBase でORMモデルを定義し、データベースのテーブルにマッピングします。

from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column

class Base(DeclarativeBase): pass

class User(Base):
    __tablename__ = "users"

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

CRUD操作

SQLAlchemyの非同期セッションメソッドを使って、基本的な作成、読み取り、更新、削除を実装します。

from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

async def create_user(db: AsyncSession, name: str, email: str):
    user = User(name=name, email=email)
    db.add(user)
    await db.commit()
    await db.refresh(user)
    return user

async def get_user(db: AsyncSession, user_id: int):
    result = await db.execute(select(User).where(User.id == user_id))
    return result.scalar_one_or_none()

Alembicによるマイグレーション

Alembicを使って、データベーススキーマのマイグレーションをバージョン管理します。

# pip install alembic
# alembic init alembic
# Edit alembic/env.py to point to your models

# Generate a migration:
# alembic revision --autogenerate -m "add users table"

# Apply:
# alembic upgrade head

httpxによる非同期HTTP呼び出し

非同期のFastAPIエンドポイントから外部APIを呼び出すには、httpx.AsyncClient を使います。

# pip install httpx
import httpx
from fastapi import FastAPI
app = FastAPI()

@app.get("/weather")
async def weather(city: str):
    async with httpx.AsyncClient() as client:
        r = await client.get(f"https://wttr.in/{city}?format=j1")
        return r.json()

バックグラウンドタスク

BackgroundTasks を使うと、レスポンス送信後に処理を実行できます。たとえば、メールの送信やキャッシュの更新などです。

from fastapi import FastAPI, BackgroundTasks
app = FastAPI()

def send_welcome_email(email: str):
    # blocking I/O — runs in background thread
    smtp_send(email, "Welcome!")

@app.post("/register")
def register(email: str, bg: BackgroundTasks):
    create_user(email)
    bg.add_task(send_welcome_email, email)
    return {"status": "registered"}

ライフサイクルイベント

lifespan コンテキストマネージャー(FastAPI 0.93以降)を使って、起動時や終了時のコードを実行します。たとえば、データベースのプールを作成できます。

from contextlib import asynccontextmanager
from fastapi import FastAPI

@asynccontextmanager
async def lifespan(app: FastAPI):
    app.state.pool = await asyncpg.create_pool(DSN)
    yield
    await app.state.pool.close()

app = FastAPI(lifespan=lifespan)

httpxによるFastAPIのテスト

サーバーを起動せずにFastAPIのエンドポイントをテストするには、ASGITransport とともに httpx.AsyncClient を使います。

import pytest, httpx
from fastapi import FastAPI
app = FastAPI()

@app.get("/ping")
async def ping(): return {"pong": True}

@pytest.mark.asyncio
async def test_ping():
    async with httpx.AsyncClient(
        transport=httpx.ASGITransport(app=app),
        base_url="http://test"
    ) as client:
        r = await client.get("/ping")
    assert r.json() == {"pong": True}

確認問題

FastAPIのルートハンドラーでは、async def と def をそれぞれいつ使うべきですか。

復習

非同期のデータベースドライバー(asyncpg、SQLAlchemy async)とともに async def エンドポイントを使います。データベースセッションはFastAPIの依存関係として管理します。レスポンス後の処理には BackgroundTasks を、起動時や終了時の処理には lifespan コンテキストマネージャーを使います。

よくある質問

「非同期エンドポイントとデータベース連携」レッスンは無料ですか?

はい。「非同期エンドポイントとデータベース連携」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Python Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Python Academyコースには全4レッスンが含まれています。

「非同期エンドポイントとデータベース連携」で何を学びますか?

非同期のルートハンドラーを記述し、SQLAlchemy でデータベースに接続します。 ブラウザで直接実行するハンズオンコードでPython Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Python Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのPython Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「非同期エンドポイントとデータベース連携」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このPython Academyレッスンでコードを書いて実行できますか?

はい。すべてのPython Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. FastAPI プロジェクトのセットアップと最初のエンドポイント
  2. パスパラメーター、クエリパラメーター、リクエストボディ
  3. 依存性注入と認証
  4. 非同期エンドポイントとデータベース連携
← Python Academyに戻る