Streamlitで家計簿アプリを作ろう!その3

Python

前回は家計簿アプリのデータ削除を作成しました。今回は、ここまでのアプリをデータベースを使って実装したいと思います。

アプリイメージ

基本的な操作やイメージは特に変わりません。内部の処理をDBを使った場合に書き換えているだけです。

今回はsqlite3を使います。

操作イメージ

コード全体

%%writefile app.py
import streamlit as st
import sqlite3
import pandas as pd

# SQLite3データベースの初期化
conn = sqlite3.connect('家計簿データ.db')
cursor = conn.cursor()

# テーブルが存在しない場合は作成
cursor.execute('''
    CREATE TABLE IF NOT EXISTS expenses (
        id INTEGER PRIMARY KEY,
        date DATE,
        item TEXT,
        amount INTEGER
    )
''')
conn.commit()

# Streamlitアプリケーションのタイトル
st.title("家計簿アプリ")

# 収支データの入力フォーム
st.header("収支の記録")
date = st.date_input("日付", pd.to_datetime("today"))
item = st.text_input("項目")
amount = st.number_input("金額", value=0, step=1)  # 金額を整数として入力

# データをデータベースに追加
if st.button("記録する"):
    cursor.execute('INSERT INTO expenses (date, item, amount) VALUES (?, ?, ?)', (date, item, amount))
    conn.commit()

# データフレームの表示
st.header("収支データ")

# 削除モードのトグルボタン
delete_mode = st.checkbox("削除モード")

if delete_mode:
    selected_rows = []  # 選択された行のリストを初期化
    st.write("収支データを選択してください:")
    for row in cursor.execute('SELECT * FROM expenses'):
        selected = st.checkbox(label="", value=False, key=row[0])
        data_row = pd.DataFrame([list(row)], columns=["ID", "日付", "項目", "金額"])
        st.write(data_row)  # データをDataFrameで表示


        if selected:
            selected_rows.append(row[0])  # 選択された行のIDを記録

    if st.button("選択した行を削除") and selected_rows:
        for row_id in selected_rows:
            cursor.execute('DELETE FROM expenses WHERE id = ?', (row_id,))
        conn.commit()
        st.success("選択した行を削除しました.")
        st.experimental_rerun()  # データを削除後に再表示

else:
    # 通常モードの一覧表示
    expenses_df = pd.read_sql('SELECT * FROM expenses', conn)
    st.write(expenses_df)

# 統計情報の表示
st.header("統計情報")
total_expenses = cursor.execute('SELECT SUM(amount) FROM expenses WHERE amount < 0').fetchone()[0]
total_income = cursor.execute('SELECT SUM(amount) FROM expenses WHERE amount > 0').fetchone()[0]
st.write("合計支出:", total_expenses)
st.write("合計収入:", total_income)

# アプリのクリアボタン
if st.button("データをクリア"):
    cursor.execute('DELETE FROM expenses')
    conn.commit()
    st.success("データがクリアされました.")

# SQLite3データベースをクローズ
conn.close()

コード解説

# SQLite3データベースの初期化
conn = sqlite3.connect('家計簿データ.db')
cursor = conn.cursor()

# テーブルが存在しない場合は作成
cursor.execute('''
    CREATE TABLE IF NOT EXISTS expenses (
        id INTEGER PRIMARY KEY,
        date DATE,
        item TEXT,
        amount INTEGER
    )
''')
conn.commit()

ここでは、SQLite3データベースを初期化しています。データベースファイル 家計簿データ.db が存在しない場合、新しいデータベースを作成し、expenses というテーブルを作成しています。このテーブルには日付、項目、金額の情報が格納されます。


# データをデータベースに追加
if st.button("記録する"):
    cursor.execute('INSERT INTO expenses (date, item, amount) VALUES (?, ?, ?)', (date, item, amount))
    conn.commit()

ここでは、ユーザーが入力したデータをデータベースに追加します。ユーザーが「記録する」ボタンをクリックすると、日付、項目、金額がデータベースの expenses テーブルに追加されます。データベースへの変更は commit() メソッドを呼び出すことで確定されます。


if delete_mode:
    selected_rows = []  # 選択された行のリストを初期化
    st.write("収支データを選択してください:")
    for row in cursor.execute('SELECT * FROM expenses'):
        selected = st.checkbox(label="", value=False, key=row[0])
        data_row = pd.DataFrame([list(row)], columns=["ID", "日付", "項目", "金額"])
        st.write(data_row)  # データをDataFrameで表示

        if selected:
            selected_rows.append(row[0])  # 選択された行のIDを記録

ここでは、削除モードが有効の場合、収支データを1行ずつ表示します。各行にはチェックボックスが表示され、ユーザーは行を選択できます。選択された行はリストに追加されます。

データは execute メソッドを使用してデータベースから取得され、DataFrameに変換して表示されます。


if st.button("選択した行を削除") and selected_rows:
    for row_id in selected_rows:
        cursor.execute('DELETE FROM expenses WHERE id = ?', (row_id,))
    conn.commit()
    st.success("選択した行を削除しました.")
    st.experimental_rerun()  # データを削除後に再表示

この部分では、ユーザーが選択した行を削除するためのボタンを作成しています。ユーザーが「選択した行を削除」ボタンをクリックすると、選択された行がデータベースから削除されます。また、削除後にデータを再表示するために st.experimental_rerun() を使用しています。


else:
    # 通常モードの一覧表示
    expenses_df = pd.read_sql('SELECT * FROM expenses', conn)
    st.write(expenses_df)

ここでは、削除モードが無効の場合、通常モードの一覧表示が行われます。データベースから収支データを取得し、PandasのDataFrameに変換して、その内容を表示します。


# 統計情報の表示
st.header("統計情報")
total_expenses = cursor.execute('SELECT SUM(amount) FROM expenses WHERE amount < 0').fetchone()[0]
total_income = cursor.execute('SELECT SUM(amount) FROM expenses WHERE amount > 0').fetchone()[0]
st.write("合計支出:", total_expenses)
st.write("合計収入:", total_income)

この部分では、収支データの統計情報を表示しています。具体的には、支出の合計金額と収入の合計金額を計算し、それらを表示しています。データベースから支出(amount < 0)と収入(amount > 0)をフィルタリングして合計を取得しています。


# アプリのクリアボタン
if st.button("データをクリア"):
    cursor.execute('DELETE FROM expenses')
    conn.commit()
    st.success("データがクリアされました.")

最後に、データをクリアするためのボタンがあります。ユーザーが「データをクリア」ボタンをクリックすると、データベース内のすべてのデータが削除され、画面に成功メッセージが表示されます。


# SQLite3データベースをクローズ
conn.close()

最後に、データベース接続をクローズしています。

GoogleColabのコード

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