【FastAPI】リレーションモデルとレスポンス【SQLAlchemy】
当ページのリンクには広告が含まれています。
今回は、FastAPI
とSQLAlchemy
を使用してデータベース作成時に
- どのようにリレーション関係の持つモデルを作成するのか
- スキーマを定義して、レスポンス形式をどのように指定するのか
について記載いたします。
【FastAPI】データベースとモデルの作成【SQLAlchemy】
FastAPIでは、djangoのように特定のORMがあるわけではなく、SQLAlchemyなどのORMライブラリを用いてデータベースへの接続を行います。 今回はSQLAlchemyを使用してデー…
【FastAPI】SQLAlchemyのCRUD操作【入門】
FastAPIとSQLAlchemyを用いて、データベースへの createreadupdatedelete 操作を実行してみます。 データベースへの接続設定とモデル作成方法は下記記事に記載していま…
FastAPIの基礎についての記事まとめ
目次
リレーション関係のモデル作成
まずはデータベースのモデルを作成します。今回は、User
とArticle
モデルを作成して
Article
にはUser
を紐づけUser
からは自分のArticle
を一緒に取得できるようにする
この2つを考えてみたいと思います。db/models.py
を作成します。
from sqlalchemy.orm import relationship
from sqlalchemy.sql.schema import ForeignKey
from db.database import Base
from sqlalchemy import Column
from sqlalchemy.sql.sqltypes import Boolean, Integer, String
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True, index=True)
username = Column(String)
email = Column(String)
password = Column(String)
is_active = Column(Boolean, default=True)
articles = relationship("Article", back_populates="user")
class Article(Base):
__tablename__ = 'articles'
id = Column(Integer, primary_key=True, index=True)
title = Column(String)
content = Column(String)
is_display = Column(Boolean)
creater_id = Column(Integer, ForeignKey('users.id'))
user = relationship("User", back_populates="articles")
Article
には
creater_id = Column(Integer, ForeignKey('users.id'))
でForeignKey
を使用してユーザーモデルと紐づけを行いました。また、各モデルから参照できるようにrelationship
を記載しています。
articles = relationship("Article", back_populates="user")
user = relationship("User", back_populates="articles")
https://docs.sqlalchemy.org/en/14/orm/basic_relationships.html
スキーマの作成
リクエスト、レスポンス用のスキーマの作成を行います。
from typing import List
from pydantic import BaseModel
class Article(BaseModel):
title: str
content: str
is_display: bool
class Config():
orm_mode = True
class UserBase(BaseModel):
username: str
email: str
password: str
class UserDisplay(BaseModel):
id: int
username: str
email: str
articles: List[Article] = []
class Config():
orm_mode = True
class User(BaseModel):
id: int
username: str
class Config():
orm_mode = True
class ArticleBase(BaseModel):
title: str
content: str
is_display: bool
creater_id: int
class ArticleDisplay(BaseModel):
title: str
content: str
is_display: bool
user: User
class Config():
orm_mode = True
ポイントはarticles: List[Article] = []
にてUser
に紐づくArticle
を紐づけています。
class UserDisplay(BaseModel):
username: str
email: str
articles: List[Article] = []
class Config():
orm_mode = True
またArticleDisplay
には、user: User
とクラスを指定しています。
class ArticleDisplay(BaseModel):
title: str
content: str
is_display: bool
user: User
class Config():
orm_mode = True
関数の作成
ユーザーと記事の作成・追加用関数を作成します。今回は更新・削除については省略します。
ユーザーの作成・取得
from db.hash import Hash
from sqlalchemy.orm.session import Session
from schemas import UserBase
from db.models import User
def create_user(db: Session, request: UserBase):
new_user = User(
username = request.username,
email = request.email,
password = Hash.get_password_hash(request.password)
)
db.add(new_user)
db.commit()
db.refresh(new_user)
return new_user
def get_user(db: Session, id: int):
return db.query(User).filter(User.id == id).first()
【FastAPI】パスワードのハッシュ化【SQLAlchemy】
データベースへパスワードのなどの機密情報を保存する場合にはハッシュ化する必要があります。 djangoなどはその辺よしなにやってくれるのですが、今回はFastAPIでのパ…
記事の作成・取得
from sqlalchemy.orm.session import Session
from schemas import ArticleBase
from db.models import Article
def create_article(db: Session, request: ArticleBase):
new_article = Article(
title = request.title,
content = request.content,
is_display = request.is_display,
user_id = request.creater_id
)
db.add(new_article)
db.commit()
db.refresh(new_article)
return new_article
def get_article(db: Session, id: int):
article = db.query(Article).filter(Article.id == id).first()
return article
エンドポイントの作成
先程作成した関数を用いてエンドポイントを作成します。
【FastAPI】SQLAlchemyのCRUD操作【入門】
FastAPIとSQLAlchemyを用いて、データベースへの createreadupdatedelete 操作を実行してみます。 データベースへの接続設定とモデル作成方法は下記記事に記載していま…
ユーザー – User
from typing import List
from schemas import UserDisplay, UserBase
from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
from db.database import get_db
from db import db_user
router = APIRouter(
prefix='/user',
tags=['user']
)
@router.post('/', response_model=UserDisplay)
def create_user(request: UserBase, db: Session = Depends(get_db)):
return db_user.create_user(db, request)
@router.get('/{id}', response_model=UserDisplay)
def get_user(id: int, db: Session = Depends(get_db)):
return db_user.get_user(db, id)
記事 – Article
from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
from db.database import get_db
from db import db_article
from schemas import ArticleBase, ArticleDisplay
router = APIRouter(
prefix='/article',
tags=['article']
)
@router.post('/', response_model=ArticleDisplay)
def create_article(request: ArticleBase, db: Session = Depends(get_db)):
return db_article.create_article(db, request)
@router.get('/{id}', response_model=ArticleDisplay)
def get_article(id: int, db: Session = Depends(get_db)):
return db_article.get_article(db, id)
エンドポイントの確認
作成したエンドポイントからレスポンスを確認してみましょう。今回作成したものは
create_user
ユーザーの追加get_user
ユーザーの1件取得create_article
記事の追加get_article
記事の1件確認
になります。
create_user
{
"id": 0,
"username": "string",
"email": "string",
"articles": []
}
get_user
{
"id": 1,
"username": "string",
"email": "string",
"articles": [
{
"title": "title1",
"content": "content1",
"is_display": true
},
{
"title": "title2",
"content": "content2",
"is_display": true
}
]
}
create_article
{
"title": "title2",
"content": "content2",
"is_display": true,
"user": {
"id": 1,
"username": "string"
}
}
get_article
{
"title": "title1",
"content": "content1",
"is_display": true,
"user": {
"id": 1,
"username": "string"
}
}
無事、作成出来ました!
参考
- https://fastapi.tiangolo.com/ja/tutorial/sql-databases/
- https://docs.sqlalchemy.org/en/14/orm/basic_relationships.html#one-to-many
- https://kumano-te.com/activities/sqlalchemy-tips
FastAPIの基礎についての記事まとめ
コメント