タイトル : 血圧降下剤の処方数量 データを表(DataGrid)で表示する
更新日 : 2024-03-24
カテゴリ : プログラミング
タグ :
opendata   
python   
fastapi   
nextjs   
datagrid   

血圧降下剤の処方数量 オープンデータを使う TOPページ

データを表でみてみましょう

前回、データをデータベースに追加できたので、データを見てみましょう

最近、nextjs + muiで仕事しているので、mui-x datagridを使います

以下みたいな感じです

画像

飲んでいる薬は後発品ですね

画像

先発品と後発品の違いがよくわからなくなってきた(後発品について調べてないので、もともとわかってないけど...)。飲んでる薬は後発品だけど先発品?と1年しか違わない?

Hは高濃度のHかな。最近の薬で効き目が強くて後発品なのか~無理に値段を下げてないよね... 副作用とか大丈夫なのかな~

ソース

フロントエンドの方です

"use client"

import { Typography, Stack } from "@mui/material";
import MenuItem from '@mui/material/MenuItem';
import Select, { SelectChangeEvent } from '@mui/material/Select';
import InputLabel from '@mui/material/InputLabel';
import { DataGrid } from '@mui/x-data-grid';

import { useEffect, useState } from "react";

import { useCategoryInfoStore } from "@/store/categoryinfo";
import { API_URL } from "@/store/settings";
import { IyCodeInfo } from "@/openapi_generated";

export default function Home() {

  const {categoryInfo, fetchCategoryInfo} = useCategoryInfoStore();
  // 血圧降下剤をデフォルトにしておく
  const [categoryId, setCategoryId] = useState("214");

  const [columns, setColumns] = useState([{field: 'id', headerName: 'ID'}]);
  const [rows, setRows] = useState([{"id": 1}]);

  const fetchData = async (iyCode:String) => {
    try {
        const response = await fetch(`${API_URL}/iycode/${iyCode}`);
        const res_json = await response.json();
        const iyCodeInfo:IyCodeInfo = res_json.iyCodeInfo
        return iyCodeInfo
    } catch (error) {
        console.error("Error fetching Category", error);
        const iyCodeInfo:IyCodeInfo = {
          iycodes: [],
          columns: [],
          rows: []
        }
        return iyCodeInfo
    }
  }

  useEffect(() => {
    fetchCategoryInfo();
    setData(categoryId)
  }, []);

  const handleCategoryChange = async (event: SelectChangeEvent) => {
    const iyCodeStr = event.target.value as string
    setCategoryId(iyCodeStr);

    setData(iyCodeStr)
  };

  const setData = async (iyCodeStr: String) => {
    const iyCodeInfo = await fetchData(iyCodeStr)

    // TODO : any使わないようにしないと
    setColumns(iyCodeInfo.columns as any)
    setRows(iyCodeInfo.rows as any)
  };

  return (
    <Stack padding={2} spacing={1}>
      <Typography color={"secondary"}>薬効分類 - 医薬品名 のテーブル表示</Typography>
      <Stack>
        { categoryInfo &&
          <Stack>
            <InputLabel id="demo-simple-select-label">
              <Typography color={"secondary"}>薬効分類</Typography>
            </InputLabel>
            <Select
              labelId="demo-simple-select-label"
              id="demo-simple-select"
              size={"small"}
              label="薬効分類"
              value={categoryId}
              sx={{width: 600}}
              onChange={handleCategoryChange}
            >
              {
                categoryInfo?.categorys.map((cinfo) => {
                  return (
                    <MenuItem key={cinfo.id} value={String(cinfo.id)}>{cinfo.name}</MenuItem>
                  )
                })
              }
            </Select>
          </Stack>
        }
      </Stack>
      <Typography color={"secondary"}>医薬品名</Typography>
      <DataGrid
        rows={rows}
        density="compact"
        rowHeight={30}
        columns={columns}
        initialState={{
          pagination: {
            paginationModel: {
              pageSize: 10,
            },
          },
        }}
        pageSizeOptions={[10,20]}
        // checkboxSelection
        disableRowSelectionOnClick
      />
    </Stack>
  );
}

routers.py

from fastapi import APIRouter, Depends

from db.database import SessionLocal
from category.category import get_categorys, CategoryInfoResponse
from iycode.iycode import get_iy_codes, IyCodeInfoResponse

router = APIRouter()

# DBのセッションを取得し、最後にクローズする
async def get_session():
    session = SessionLocal()
    try:
        yield session
    finally:
        session.close()


@router.get("/category", response_model=CategoryInfoResponse)
async def api_get_category(session=Depends(get_session)) -> CategoryInfoResponse:
    rv: CategoryInfoResponse = get_categorys(session)
    return rv


@router.get("/iycode/{category_id}", response_model=IyCodeInfoResponse)
async def api_get_iy_codes(category_id: int, session=Depends(get_session)) -> IyCodeInfoResponse:
    rv: CategoryInfoResponse = get_iy_codes(session, category_id)
    return rv

category.py

from typing import List
from pydantic import BaseModel
from typing import List
from dataclasses import dataclass

from db.models.iy_category import IyCategory

@dataclass
class CategoryInfoItem:
    id: int
    name: str

@dataclass
class CategoryInfo:
    categorys: List[CategoryInfoItem]

class CategoryInfoResponse(BaseModel):
    categoryInfo: CategoryInfo


def get_categorys(session) -> CategoryInfoResponse:

    categorys = []

    q = session.query(IyCategory)
    for r in q:
        categorys.append(
            CategoryInfoItem(
                id=r.id, name=r.name
            )
        )

    category_info = CategoryInfo(categorys=categorys)
    return CategoryInfoResponse(categoryInfo=category_info)

iy_code.pyの記載は今回は省略。後発品の列の作り方のソースがカッコわるすぎ