関連記事

FastAPI + postgressのアプリ構築メモ part.1 環境構築 (イマココ)
FastAPI + postgressのアプリ構築メモ part.2 CREATE
FastAPI + postgressのアプリ構築メモ part.3 READ

今回やること

FastAPIめっちゃ便利だけど、DB使うときのメモが案外無かったので書いておく

多分だけど

が王道だとおもう

仮想環境の構築

dockerとか使った方がいい場合もあるだろうけど
とりあえず今回はvenvで

python -m venv porukatu-env
source porukatu-env/bin/activate

FastAPIのインストール

https://fastapi.tiangolo.com/tutorial/

pip install fastapi
pip install uvicorn

Postgresのインストールとデータベースの作成

https://zero-cheese.com/2474/

OSとかによって違うと思うので適宜インストールして
ユーザとパスワードがあれば接続できる状態にしておく

databaseの作成

sudo -i -u postgres
psql
create database porukatu lc_collate='ja_JP.UTF-8' lc_ctype='ja_JP.UTF-8' template='template0';

FastAPIの初期化

main.py

import uvicorn
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
async def root():
    return {"message": "Hello World"}

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8889)

とりあえずこれでサーバ動いていることを確認する

img.jpg

dbとの接続

pip install alembic sqlalchemy
pip install psycopg2-binary==2.9.3
alembic init porukatu

databse.py

from sqlalchemy import create_engine
from sqlalchemy.orm import declarative_base

# for dev
engine = create_engine('postgresql://{username}:{password}@localhost:5432/porukatu')

Base = declarative_base()

models.py

from sqlalchemy import Column, DateTime, Text, Integer
from sqlalchemy.sql.functions import current_timestamp
from sqlalchemy.ext.declarative import declared_attr
from database import Base

class TimestampMixin(object):
    @declared_attr
    def created_at(cls):
        return Column(DateTime, default=current_timestamp(), nullable=False)

    @declared_attr
    def updated_at(cls):
        return Column(
            DateTime, default=current_timestamp(), nullable=False
        )
 
class NEWS(Base, TimestampMixin):
    __tablename__ = 'news'
 
    id = Column(Integer, primary_key=True)
    title = Column(Text, nullable=False)
    link  = Column(Text, nullable=False)

alembic.ini の編集

sqlalchemy.url = postgresql://{username}:{password}@localhost:5432/onsen_mania

porukatu/env.py

追記・編集することをメモ

from models import NEWS
from database import Base
target_metadata = Base.metadata

def run_migrations_online() -> None:
    """Run migrations in 'online' mode.

    In this scenario we need to create an Engine
    and associate a connection with the context.

    """
    connectable = engine_from_config(
        config.get_section(config.config_ini_section),
        prefix="sqlalchemy.",
        poolclass=pool.NullPool,
    )
    url = config.get_main_option("sqlalchemy.url")

    with connectable.connect() as connection:
        context.configure(
            connection=connection, url=url, target_metadata=target_metadata
        )

        with context.begin_transaction():
            context.run_migrations()

migration

alembic revision --autogenerate -m "create tables"

これで
porukatu/versions/

配下に下記のmigrationスクリプトファイルができます

alembic upgrade head

これを実行した後

sudo -i -u postgres
psql
\c porukatu
\dt

              List of relations
 Schema |      Name       | Type  |  Owner   
--------+-----------------+-------+----------
 public | alembic_version | table | omaemona
 public | news            | table | omaemona
(2 rows)

これでnewsというテーブルが作成されていますね

以後

alembic revision --autogenerate -m "message" # マイグレーションファイル作成
alembic upgrade head # create
alembic downgrade base # erase all

が基本となってテーブルの更新作業が進んでいきます。

modelを書き換えると、マイグレーションファイルを自動的に生成してくれるのでお作法さえ覚えてしまえば便利ですね