2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

FastAPI: SQLAlchemy で MariaDB を使う

2
Last updated at Posted at 2022-04-24

次のページを参考にしました。
SQL (Relational) Databases

Ubuntu でのライブラリーのインストール

sudo apt install libmysqlclient-dev
sudo apt install python3-mysqldb

MariaDB にデータベースを作成

host ='localhost'
data_base = 'db_test'
user ='scott'
password = 'tiger123'
$ sudo mariadb -uroot

MariaDB [(none)]> create schema db_test
MariaDB [(none)]> create user 'scott'@'localhost' identified by 'tiger123';
MariaDB [(none)]> grant all on db_test.* to 'scott'@'localhost';
MariaDB [(none)]> flush privileges;
MariaDB [(none)]> exit

データベースが出来ていることの確認

$ mariadb -uscott -ptiger123 db_test
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 32
Server version: 11.8.3-MariaDB-1build1 from Ubuntu -- Please help get to 10k stars at https://github.com/MariaDB/Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [db_test]>

プログラム

$ tree server
server
├── __init__.py
├── crud.py
├── database.py
├── main.py
├── models.py
└── schemas.py
crud.py
from sqlalchemy.orm import Session

from . import models, schemas

def get_user(db: Session, user_id: int):
    return db.query(models.User).filter(models.User.id == user_id).first()

def get_user_by_email(db: Session, email: str):
    return db.query(models.User).filter(models.User.email == email).first()

def get_users(db: Session, skip: int = 0, limit: int = 100):
    return db.query(models.User).offset(skip).limit(limit).all()

def create_user(db: Session, user: schemas.UserCreate):
    fake_hashed_password = user.password + "notreallyhashed"
    db_user = models.User(email=user.email, hashed_password=fake_hashed_password, name=user.name)
    db.add(db_user)
    db.commit()
    db.refresh(db_user)
    return db_user
database.py
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
#
host ='localhost'
data_base = 'db_test'
user ='scott'
password = 'tiger123'
#
db_url = "mysql://" + user + ":" + password + "@" + host + "/" + data_base
#

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

Base = declarative_base()
main.py
from fastapi import Depends, FastAPI, HTTPException
from sqlalchemy.orm import Session

from . import crud, models, schemas
from .database import SessionLocal, engine

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

app = FastAPI()


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


@app.post("/users/", response_model=schemas.User)
def create_user(user: schemas.UserCreate, db: Session = Depends(get_db)):
    db_user = crud.get_user_by_email(db, email=user.email)
    if db_user:
        raise HTTPException(status_code=400, detail="Email already registered")
    return crud.create_user(db=db, user=user)


@app.get("/users/", response_model=list[schemas.User])
def read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
    users = crud.get_users(db, skip=skip, limit=limit)
    return users


@app.get("/users/{user_id}", response_model=schemas.User)
def read_user(user_id: int, db: Session = Depends(get_db)):
    db_user = crud.get_user(db, user_id=user_id)
    if db_user is None:
        raise HTTPException(status_code=404, detail="User not found")
    return db_user
models.py
from sqlalchemy import Boolean, Column, ForeignKey, Integer, String
from sqlalchemy.orm import relationship

from .database import Base


class User(Base):
    __tablename__ = "users"

    id = Column(Integer, primary_key=True, index=True)
    email = Column(String(255), unique=True, index=True)
    hashed_password = Column(String(255))
    is_active = Column(Boolean, default=True)
    name = Column(String(255), index=True)
schemas.py
from pydantic import BaseModel

class UserBase(BaseModel):
    email: str

class UserCreate(UserBase):
    password: str
    name: str

class User(UserBase):
    id: int
    is_active: bool
    name: str

    class Config:
        orm_mode = True

サーバーの実行

uvicorn server.main:app --reload

テストスクリプト

データの作成

http_create.sh
http 'http://127.0.0.1:8000/users/' email="aa@bbb.com" password="secret" name="Tom"
http 'http://127.0.0.1:8000/users/' email="bb@bbb.com" password="secret" name="Betty"
http 'http://127.0.0.1:8000/users/' email="cc@bbb.com" password="secret" name="John"

データの取得

http_get.sh
http 'http://127.0.0.1:8000/users/?skip=0&limit=100'

id を指定してデータの取得

http_user.sh
http 'http://127.0.0.1:8000/users/1'

実行結果

$ ./http_user.sh 
HTTP/1.1 200 OK
content-length: 59
content-type: application/json
date: Fri, 19 May 2023 05:45:58 GMT
server: uvicorn

{
    "email": "aa@bbb.com",
    "id": 1,
    "is_active": true,
    "name": "Tom"
}

確認したバージョン

$ python
Python 3.13.7 (main, Aug 20 2025, 22:17:40) [GCC 15.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.

>>> import fastapi
>>> fastapi.__version__
'0.115.11'

>>> import sqlalchemy
>>> sqlalchemy.__version__
'2.0.40'
2
1
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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?