第二章:大腦記憶中樞 - FastAPI 完美串接 Supabase 資料庫

在之前的 Course 1 和 2 裡,我們學會了如何在前端使用 JavaScript (在 React 或 Astro 裡) 來連接 Supabase,把資料撈出來顯示在網頁上。 現在我們來到了後端領域!我們的 Line 機器人不能只有「金魚腦」,它必須記住員工每天的打卡時間。 這章我們要教你如何使用 Python 來連接 Supabase 雲端資料庫,並且把 Line Bot 傳來的打卡紀錄,安全且穩定地寫進去!

🎯 本章目標

  1. 學習如何在 FastAPI (Python 環境) 中整合 Supabase SDK。
  2. 將資料庫連線抽離成獨立的模組 (database.py),這是企業級專案的標準架構。
  3. 實作真實的「上班打卡」邏輯。
  4. 將打卡資料成功 INSERT 到 Supabase 資料庫中。

🔗 第一步:初始化 Supabase 客戶端 (Client)

在後端專案中,我們絕對不能把資料庫連線密碼直接寫死在 main.py 裡面,否則一旦上傳到 GitHub,你的資料庫就會被全世界看光光,甚至被惡意刪庫。 我們必須把連線邏輯獨立寫在一個檔案中,並從 .env 讀取機密資訊。

🔥【Vibe Prompt 實戰咒語】 我正在使用 Python FastAPI 開發後端。請教我如何使用 supabase-py 套件來連接我的雲端資料庫。 1. 幫我建立一個名為 database.py 的獨立檔案。 2. 裡面必須使用 dotenv 套件從 .env 檔案中讀取 SUPABASE_URL 和 SUPABASE_KEY。 3. 建立一個名為 supabase_client 的全域變數 (透過 create_client 產生),讓我的其他檔案可以直接 import 它來操作資料庫。 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: 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,你就可以直接對資料庫下指令了!


⏱️ 第二步:實作打卡寫入邏輯

假設我們在 Supabase 裡,已經建立好一張名為 punch_records 的資料表。 這張表裡面包含了三個欄位:user_id (字串)、punch_type (字串,'in' 或 'out')、created_at (自動產生的時間戳記)。

我們要在收到 Line 傳來文字「上班」的瞬間,把資料寫進去。

🔥【Vibe Prompt 實戰咒語】 在我的 main.py 中,我已經寫好了一個處理 Line 文字訊息的 Webhook (handle_message)。 請幫我加上寫入資料庫的邏輯: 1. 判斷如果使用者輸入的文字 (event.message.text) 是 "上班"。 2. 請 import database.py 裡面的 supabase_client。 3. 將一筆紀錄 INSERT 到 punch_records 資料表。欄位 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) 是處於「鎖定狀態」的。如果你沒有設定 RLS 政策允許 INSERT 操作,任何嘗試從外部寫入資料的行為都會被無情拒絕。 解決方案:請前往 Supabase 網頁後台,進入 Authentication -> Policies,為你的 punch_records 表新增一條「允許所有的 Insert 權限」的 Policy,你的程式碼就能順利寫入囉!


💼 [商業應用場景] 數據才是最值錢的資產

現在,你的 Line 機器人已經不再只是個會重複你說話的「無腦鸚鵡」,它進化成了一個能把現實世界資料 (打卡紀錄) 長期儲存在雲端的商業系統!

當這些打卡紀錄累積了一個月,你就能利用它算薪水、分析員工遲到率、甚至作為法院上的出勤證據。 但只有資料寫入是不夠的,純文字回覆「打卡成功」實在太無聊了,很難讓老闆覺得這套系統值幾萬塊。 下一章,我們將教你如何使用 Line 獨家的 JSON 語法,送出超炫砲的 Flex Message (氣泡卡片),這將是提升專案報價的關鍵絕招!

解鎖完整教學內容

本章為付費內容。加入專案即可解鎖超過 5000 字的深度解析,包含 10 個以上神級 Prompt 與真實 Source Code 範例!