FastAPI で postgresql データ取得 -プログラム説明-【Ubuntu22】

Python
スポンサーリンク
スポンサーリンク

はじめに

前回は FastAPI で postgresql のデータを取得しました。

今回はFastAPIのプログラムについて説明していきます。

前提条件

  • Ubuntu22.04
  • Python == 3.10.12
  • FastAPI がインストールされている

前回のプログラムを再掲

始めに、前回のプログラムを再掲しておきます。

import os
import uvicorn
from dotenv import load_dotenv
load_dotenv()
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from sqlalchemy import create_engine, Integer, Text, Column
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

app = FastAPI()

origins = [
    "http://127.0.0.1:83",
    "http://localhost:3000",
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

POSTGRES_USER = os.environ['POSTGRES_USER']
POSTGRES_PASSWORD = os.environ['POSTGRES_PASSWORD']
POSTGRES_SERVER = os.environ['POSTGRES_SERVER']
POSTGRES_PORT = os.environ['POSTGRES_PORT']
POSTGRES_DB = os.environ['POSTGRES_DB']

SQLALCHEMY_DATABASE_URL = "postgresql://{0}:{1}@{2}:{3}/{4}".format(
    POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_SERVER, POSTGRES_PORT, POSTGRES_DB
)
engine = create_engine(
    SQLALCHEMY_DATABASE_URL
)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
session = SessionLocal()

Base = declarative_base()
class User(Base):
    __tablename__ = "user1_list"
    user_id = Column("id",
                        Integer,
                        primary_key=True,
                        autoincrement=True)
    name = Column("name",
                     Text,
                     nullable=False)


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

@app.get("/users/")
def get_all_user():
    user_list = []
    for r in session.query(User):
        user_list.append(r)
    return user_list

@app.get("/users/{id}")
def get_one_user(id):
    user_list = []
    for r in session.query(User).where(User.user_id == id):
        user_list.append(r)
    return user_list

@app.post("/add_user/")
def add_one_user():
    user = User(name="hello")
    session.add(user)
    session.commit()
    return {"result": "success"}

@app.put("/update_user/{id}")
def update_user(id):
    query = session.query(User).where(User.user_id == id).first()
    query.name = "v2name is my name"
    session.commit()
    return {"result": "success"}

@app.delete("/delete_user/{id}")
def delete_user(id):
    query = session.query(User).where(User.user_id == id).delete()
    session.commit()
    return {"result": "success"}


if __name__ == "__main__":
    uvicorn.run(app, host="127.0.0.1", port=8000)
    session.close()

上から順に説明していきます。

import文

import os
import uvicorn
from dotenv import load_dotenv
load_dotenv()
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from sqlalchemy import create_engine, Integer, Text, Column
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

load_dotenv() で 同じディレクトリ内の .env ファイルを読み込みます。

FastAPI の初期設定

app = FastAPI()

origins = [
    "http://127.0.0.1:83",
    "http://localhost:3000",
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

FastAPI をインスタンス化してから、初期設定をしていきます。

origins は FastAPI と通信可能な URL を指定します。
今回は React のローカルサーバーと Nginx の URL を指定しました。

postgres の設定が保存された .env を読込

POSTGRES_USER = os.environ['POSTGRES_USER']
POSTGRES_PASSWORD = os.environ['POSTGRES_PASSWORD']
POSTGRES_SERVER = os.environ['POSTGRES_SERVER']
POSTGRES_PORT = os.environ['POSTGRES_PORT']
POSTGRES_DB = os.environ['POSTGRES_DB']

import 文の load_dotenv() で環境変数に登録されたので、os.environ で各種情報を取得していきます。

自身で設定した postgres の設定に合わせてください。

postgresql と接続

SQLALCHEMY_DATABASE_URL = "postgresql://{0}:{1}@{2}:{3}/{4}".format(
    POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_SERVER, POSTGRES_PORT, POSTGRES_DB
)
engine = create_engine(
    SQLALCHEMY_DATABASE_URL
)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
session = SessionLocal()

create_engine(URL) でデータベースのエンジンを作成します。
この時点では、接続はまだ確立されていません。

続いて、sessionmaker でセッション情報を作成します。bind=engine でエンジン指定します。

session = SessionLocal() でセッション情報をインスタンス化し、接続を確立します。
終了するときは、session.close() です。

データベースのテーブル情報を作成

Base = declarative_base()
class User(Base):
    __tablename__ = "user1_list"
    user_id = Column("id",
                        Integer,
                        primary_key=True,
                        autoincrement=True)
    name = Column("name",
                     Text,
                     nullable=False)

Base = declarative_base() で、テーブルのベースを作成します。

class User は、テーブルの情報を記述していきます。
__tablename__ はpostgresqlで作成したテーブル名を入力します。

user_id, name は、テーブル情報の各カラムを指定します。
primary_key が最低一つは必要です。

FastAPI でルーティング指定

ルーティング(表現合ってないです)を設定していきます。

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

ルートパス(“/”) の GET メソッドで json データを return します。
基本的に、json データをそのまま流せます。

postgresql から取得したデータを返却

@app.get("/users/")
def get_all_user():
    user_list = []
    for r in session.query(User):
        user_list.append(r)
    return user_list

@app.get("/users/{id}")
def get_one_user(id):
    user_list = []
    for r in session.query(User).where(User.user_id == id):
        user_list.append(r)
    return user_list

データベースからのデータ取得は session.query() で取得できます。
イテレータを返すので、for 文で取得していきます。

また、URL に、{id} を指定すると、URL から数値を取得可能です。
session.query().where() で条件に合うデータを特定して取得できます。

テーブルにデータを挿入

@app.post("/add_user/")
def add_one_user():
    user = User(name="hello")
    session.add(user)
    session.commit()
    return {"result": "success"}

POST メソッドでデータを挿入していきます。

INSERT 自体は簡単で、session.add() で挿入できます。
session.commit() でデータが反映されます。

テーブルデータを更新

@app.put("/update_user/{id}")
def update_user(id):
    query = session.query(User).where(User.user_id == id).first()
    query.name = "v2name is my name"
    session.commit()
    return {"result": "success"}

PUT メソッドは session.query() のイテレータから一つ取り出す first() を実行してから、中身を変更するだけです。
session.commit() で実際にデータを更新します。

テーブルデータを削除

@app.delete("/delete_user/{id}")
def delete_user(id):
    query = session.query(User).where(User.user_id == id).delete()
    session.commit()
    return {"result": "success"}

テーブルデータは、where 条件にマッチするものを削除します。
これも、session.commit() で反映されます。

main 関数

if __name__ == "__main__":
    uvicorn.run(app, host="127.0.0.1", port=8000)
    session.close()

uvicorn で API サーバーを起動します。
サーバー終了時には postgresql のセッションを閉じておきます。

FastAPI の特徴

FastAPIの特徴であるドキュメント自動生成を確認していきます。

http://127.0.0.1:8000/docs にアクセスすることで確認できます。

おわりに

今回は FastAPI のプログラムについて説明しました。

今までの説明をつなげると、Nginx + React + FastAPI + Postgresql のWebアプリを作成することができます。

次回は FastAPI のその他の機能について説明していければと思います。

コメント

タイトルとURLをコピーしました