第二章:大脳記憶中枢 - FastAPI で Supabase データベースを完璧に連携させる
これまでの Course 1 と 2 では、フロントエンドで JavaScript (React や Astro 内) を使って Supabase に接続し、データを取得してウェブページに表示する方法を学びました。 今度はバックエンドの領域へ!私たちの Line ボットは「金魚の記憶」だけではいけません。従業員の毎日の出退勤時間を記憶する必要があります。 この章では、Python を使って Supabase クラウドデータベースに接続し、Line Bot から送信された打刻記録を安全かつ確実に書き込む方法を教えます!
🎯 本章の目標
- FastAPI (Python 環境) で Supabase SDK を統合する方法を学ぶ
- データベース接続を独立したモジュール (database.py) に分離する(企業レベルのプロジェクト標準構成)
- 実際の「出勤打刻」ロジックを実装する
- 打刻データを Supabase データベースに正常に INSERT する
🔗 ステップ1:Supabase クライアントの初期化
バックエンドプロジェクトでは、データベース接続パスワードを直接 main.py にハードコーディングしてはいけません。GitHub にアップロードすると、データベースが全世界に晒され、悪意のある削除の危険にさらされます。
接続ロジックを別ファイルに分離し、.env から機密情報を読み取る必要があります。
🔥【Vibe Prompt 実戦呪文】
Python FastAPI でバックエンドを開発しています。supabase-py パッケージを使ってクラウドデータベースに接続する方法を教えてください。1. database.py という独立したファイルを作成してください2. dotenv パッケージを使って .env ファイルから SUPABASE_URL と SUPABASE_KEY を読み取るようにしてください3. create_client で生成される supabase_client というグローバル変数を作成し、他のファイルから直接インポートしてデータベース操作できるようにしてください4. 必要な pip パッケージインストールコマンドも記載してください
AI はまずパッケージインストールを指示します:
pip install supabase
そしてこの非常に簡潔な database.py を生成します:
import os
from supabase import create_client, Client
from dotenv import load_dotenv
# .env ファイルから環境変数を読み込む
load_dotenv()
# 機密URLとキーを読み取る(実際の文字列をここに書いてはいけません!)
url: str = os.environ.get("SUPABASE_URL")
key: str = os.environ.get("SUPABASE_KEY")
# 単一接続インスタンスを作成
supabase_client: Client = create_client(url, key)
このファイルがあれば、プロジェクトのどこからでも from database import supabase_client と書くだけで、直接データベースにコマンドを発行できます!
⏱️ ステップ2:打刻書き込みロジックの実装
Supabase に punch_records というテーブルが既に作成されていると仮定します。
このテーブルには3つのカラムがあります:user_id (文字列)、punch_type (文字列、'in' または 'out')、created_at (自動生成されるタイムスタンプ)。
Line から「出勤」というテキストが送信された瞬間に、データを書き込む必要があります。
🔥【Vibe Prompt 実戦呪文】
main.py に Line テキストメッセージを処理する Webhook (handle_message) が既に書かれています。データベース書き込みロジックを追加してください:1. ユーザーが入力したテキスト (event.message.text) が「出勤」かどうかを判定2. database.py から supabase_client をインポート3. punch_records テーブルに1レコード INSERT。user_id には Line から送信された event.source.user_id を、punch_type には 'in' を設定4. 書き込み中に Exception が発生した場合(例:ネットワーク切断)、エラーを捕捉し「システムが混雑しています、打刻に失敗しました」をユーザーに返信5. 書き込みが成功した場合、line-bot-sdk を使って「出勤打刻成功!社長があなたを愛しています!」をユーザーに返信
AI はこの書き込みロジックを元の Webhook コードに完璧に統合します:
from database import supabase_client
from linebot.v3.messaging import TextMessage, ReplyMessageRequest
# テキストメッセージ受信時の処理関数
@handler.add(MessageEvent, message=TextMessageContent)
def handle_message(event):
user_id = event.source.user_id
text = event.message.text
if text == "出勤":
try:
# 💡 Supabase を呼び出してリモート書き込み
data = supabase_client.table("punch_records").insert({
"user_id": user_id,
"punch_type": "in"
}).execute()
# この行に到達すれば書き込み成功!
reply_text = "出勤打刻成功!社長があなたを愛しています!"
print(f"✅ ユーザー {user_id} の打刻データ書き込み成功")
except Exception as e:
# 発生する可能性のあるシステムエラーを捕捉(サーバークラッシュ防止)
reply_text = "システムが混雑しています、しばらくしてから再試行してください!"
print(f"❌ 書き込み失敗: {e}")
else:
reply_text = "理解できませんでした、「出勤」または「退勤」と入力してください。"
# 組み立てた reply_text を Line サーバーに返信
with ApiClient(configuration) as api_client:
line_bot_api = MessagingApi(api_client)
line_bot_api.reply_message_with_http_info(
ReplyMessageRequest(
reply_token=event.reply_token,
messages=[TextMessage(text=reply_text)]
)
)
⚠️ [よくある落とし穴] Row Level Security (RLS) の設定忘れ
スマートフォンで「出勤」と入力して喜んでいると、FastAPI がエラーを吐き出します:
postgrest.exceptions.APIError: {'code': '401', 'message': 'new row violates row-level security policy'}
これは Python のコードが間違っているのではありません!Supabase はセキュリティを極めて重視するシステムだからです。
デフォルトでは、新しく作成したテーブル (Table) は「ロック状態」になっています。INSERT 操作を許可する RLS ポリシーを設定しない限り、外部からのデータ書き込み試行はすべて拒否されます。
解決策:Supabase のウェブ管理画面で、Authentication -> Policies に移動し、punch_records テーブルに「すべての Insert 権限を許可」する Policy を追加すれば、コードは正常に書き込めるようになります!
💼 [ビジネス応用シナリオ] データこそ最も価値ある資産
今、あなたの Line ボットは単に言葉を繰り返す「無脳なオウム」ではなく、現実世界のデータ(打刻記録)をクラウドに長期保存できるビジネスシステムに進化しました!
これらの打刻記録が1ヶ月分蓄積されれば、給与計算や従業員の遅刻率分析、さらには法廷での出勤証拠として使用できます。 しかし、データ書き込みだけでは不十分です。「打刻成功」というテキスト返信だけでは、社長にこのシステムが数万円の価値があるとは思わせられません。 次の章では、Line 独自の JSON 構文を使用して超豪華な Flex Message (バブルカード) を送信する方法を教えます。これがプロジェクトの価格を引き上げる決定的なテクニックになります!