Raspberryでstreamlitを勉強してみる②

**前回の内容**
[Raspberryでstreamlitを勉強してみる①](https://qiita.com/MasahiroShouya/items/f2e37210c7d84ef062a1 "前回の記事")
上記リンク先にて、Raspberry PI に、streamlitのサービス登録を掲載しています。

**今回の内容**
streamlitでは、グラフ表示が出来るので、データベースを利用したサンプルを作ってみたいと思います。

**準備作業**
前回の内容で、実行してなければ、以下は実行しておきましょう。
（Raspberry PI OS-Lite で準備すると、プログラムリストの更新は必須です）
sudo apt-get update
sudo apt-get upgrade
今回の内容を実施する為、Postgresを利用したいと思いますが、以前の記事を参考に準備します。
[安価なWeb開発勉強環境の構築②](https://qiita.com/MasahiroShouya/items/691601d10a85f4bae371 "以前の記事")
※ Postgresのインストールから、SQLAlchemyまで準備しましょう。

```diff_conf:フォルダ構成
└── test
    ├── main.py　 　（streamlitで起動するプログラム）
    ├── sidebar.py　（画面左のメニュー）
    ├── config.py　 （共通処理：DBの接続情報）
    ├── ins1.py　　 （アップロード処理するプログラム）
    └── graph.py　　（グラフ表示プログラム）
```
```diff_python:main.py
import streamlit as st
from sidebar import sidebar_process
from graph import show_graph as grad
from ins1 import upld as zupld
if __name__ == "__main__":
    sel = sidebar_process()
    if sel == "アップロード":
        zupld()
    else:
        grad()
```
```diff_python:sidebar.py
import streamlit as st
def sidebar_process():
    opt1 = ["アップロード", "グラフ表示"]
    zmode = st.sidebar.selectbox("処理選択", opt1)
    return zmode
```
```diff_python:config.py
import os
class Config:
    DATABASE = 'postgresql://flask1:パスワード@localhost:5432/flask1'
```
```diff_python:ins1.py
import streamlit as st
import pandas as pd
from sqlalchemy import create_engine, Table, MetaData
from sqlalchemy.orm import sessionmaker
from config import Config

conf = Config()
engine = create_engine(conf.DATABASE)         # SQLAlchemyエンジンの作成
Session = sessionmaker(bind=engine)
session = Session()
metadata = MetaData()
metadata.reflect(bind=engine)
t_kbn = Table('t_kbn', metadata, autoload_with=engine)

def upld():      # ファイルアップロード
    uploaded_file = st.file_uploader("ファイルをアップロードしてください", type=["csv"])
    if uploaded_file is not None:        # CSVファイルを読み込み
        df = pd.read_csv(uploaded_file, header=None)
        df.columns = ['zkbn', 'znum1', 'znum2', 'zstdate', 'zendate', 'val1', 'val2', 'val3']
        df['zstdate'] = pd.to_datetime(df['zstdate'].str.replace("'", ""), format='%Y-%m-%d')
        df['zendate'] = pd.to_datetime(df['zendate'].str.replace("'", ""), format='%Y-%m-%d')
        st.write("アップロードしたデータ:")        # データ確認
        st.write(df)
        if st.button('データベースに挿入'):        # インサート処理
            try:
                with engine.begin() as conn:
                    conn.execute(t_kbn.delete())        # 一度全削除
                insert_data = df.to_dict(orient='records')
                with engine.begin() as conn:
                    conn.execute(t_kbn.insert(), insert_data)
                st.success("データを挿入しました！")
            except Exception as e:
                st.error(f"データベースへの挿入に失敗しました: {e}")
```

```diff_python:graph.py
import streamlit as st
import pandas as pd
from sqlalchemy import create_engine, MetaData, Table
from sqlalchemy.orm import sessionmaker
from config import Config

conf = Config()
engine = create_engine(conf.DATABASE)       # SQLAlchemyエンジンの作成
Session = sessionmaker(bind=engine)
session = Session()

def fetch_data():    # zkbnが'ZKBN2'のデータを抽出
    metadata = MetaData()
    t_kbn = Table('t_kbn', metadata, autoload_with=engine)
    query = session.query(t_kbn).filter(t_kbn.c.zkbn == 'ZKBN2')
    result = query.all()
    data = [{'znum1': row.znum1, 'znum2': float(row.znum2)} for row in result]
    df = pd.DataFrame(data)
    return df

def show_graph():    # グラフを表示
    df = fetch_data()
    if not df.empty:
        st.write("グラフ表示:")
        st.line_chart(df, x='znum1')
    else:
        st.write("No data found.")
```
プログラムの準備が終わりましたら、パソコンより「http://（RaspberryのIPアドレス）:8501」へアクセスします。
（systemctlでサービス起動しているので、プログラム変更は即時適用されます）
ファイルのアップロード画面が表示されますので、以下のファイルを用意してアップロードしましょう。
（テーブルは、[安価なWeb開発勉強環境の構築②](https://qiita.com/MasahiroShouya/items/691601d10a85f4bae371 "以前の記事") で作成したt_kbnを流用してます）
```diff_python:アップロードファイル（拡張子はcsv）
ZKBN2,1,1.1,'2024-10-08','2024-10-08','','',''
ZKBN2,2,2.2,'2024-10-08','2024-10-08','','',''
ZKBN2,3,3.3,'2024-10-08','2024-10-08','','',''
ZKBN2,4,4.4,'2024-10-08','2024-10-08','','',''
```
正常にアップロードされたら、サイドバーの「処理選択」から「グラフ表示」を選択しましょう。
折れ線グラフが表示されたら終了です。　お疲れさまでした。