【FastAPI】でMySQLに接続する方法

2024/08/12に公開

前回の記事では、FastAPIとDockerを使って簡単なウェブAPIを作成する方法を紹介しました。
https://zenn.dev/xronotech/articles/273c0bb59173d8
今回は、その続きとしてFastAPIでMySQLデータベースに接続する方法を紹介します。

環境の準備

まず、MySQLコンテナを追加してDocker Composeで環境を整えます。前回のプロジェクト構成にMySQLコンテナを追加します。

ディレクトリ構成

基本的に前回と同じディレクトリ構成を使いますが、docker-compose.ymlにMySQLサービスを追加します。

fastapi-docker-example/
│
├── app/
│   ├── config
│   │    └── database.py
│   ├── models
│   │    └── user.py
│   └── main.py
├── docker-compose.yml
├── Dockerfile
├── requirements.txt
└── README.md

Docker Composeの設定

docker-compose.ymlを以下のように編集して、MySQLサービスを追加します。

docker-compose.yml
services:
  web:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "8000:8000"
    volumes:
      - ./app:/app
    depends_on:
      - db

  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: rootpassword
      MYSQL_DATABASE: testdb
      MYSQL_USER: testuser
      MYSQL_PASSWORD: testpassword
    ports:
      - "3306:3306"

必要なパッケージのインストール

次に、FastAPIとSQLAlchemy、およびMySQLドライバの依存関係を追加します。requirements.txtに以下を追加します。

requirements.txt
fastapi
uvicorn
+sqlalchemy
+pymysql

データベース接続設定

app/config/database.pyを作成し、データベース接続の設定を行います。

database.py
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

SQLALCHEMY_DATABASE_URL = "mysql+pymysql://testuser:testpassword@db/testdb"

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

Base = declarative_base()

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

Userモデルの定義

app/models/user.pyを作成し、データベースのモデルを定義します。ここでは、簡単なユーザーモデルを定義します。

models.py
from sqlalchemy import Column, Integer, String
from .database import Base

class User(Base):
    __tablename__ = "users"

    id = Column(Integer, primary_key=True, index=True)
    name = Column(String(50), index=True)
    email = Column(String(50), unique=True, index=True)
    hashed_password = Column(String(100))

データベースのマイグレーション

データベースのテーブルを作成するために、以下のスクリプトをapp/main.pyに追加します。

main.py
from fastapi import FastAPI
+from .database import engine, Base
+from .models import User

app = FastAPI()

+Base.metadata.create_all(bind=engine)

@app.get("/")
def read_root():
    return {"message": "Hello, World!"}

CRUD操作の実装

次に、CRUD操作を実装します。以下はユーザーの作成と取得を行うエンドポイントの例です。

main.py
from fastapi import FastAPI, Depends, HTTPException
from sqlalchemy.orm import Session
from . import models, database

app = FastAPI()

models.Base.metadata.create_all(bind=database.engine)

@app.get("/")
def read_root():
    return {"message": "Hello, World!"}

@app.post("/users/", response_model=models.User)
def create_user(user: models.UserCreate, db: Session = Depends(database.get_db)):
    db_user = db.query(models.User).filter(models.User.email == user.email).first()
    if db_user:
        raise HTTPException(status_code=400, detail="Email already registered")
    new_user = models.User(name=user.name, email=user.email, hashed_password=user.hashed_password)
    db.add(new_user)
    db.commit()
    db.refresh(new_user)
    return new_user

@app.get("/users/{user_id}", response_model=models.User)
def read_user(user_id: int, db: Session = Depends(database.get_db)):
    return db.query(models.User).filter(models.User.id == user_id).first()

アプリケーションの起動

全ての設定が完了したら、以下のコマンドを実行してアプリケーションを起動します。

docker-compose up --build

コンテナが起動したら、ブラウザでhttp://localhost:8000にアクセスして、APIが正常に動作することを確認します。

まとめ

これで、FastAPIとMySQLを使った簡単なウェブAPIの環境が整いました。FastAPIの強力な機能とMySQLのデータベースを活用して、さらに複雑なアプリケーションを作成してみてください。次回は、認証機能や他のデータベース操作についても触れていきますので、ぜひお楽しみに!

株式会社Xronotech

Discussion