跳轉至

建立 2026-10-03 更新 2026-10-03

Python DB-API

Python DB-API(PEP 249)是 Python 存取關聯式資料庫的共通介面標準,sqlite3、psycopg、PyMySQL、mysql-connector-python 都遵循它。因此只要學會「連線 → cursor → execute → fetch → commit → close」這套流程,換資料庫時程式幾乎不用改,只需要換驅動與連線參數。

標準流程

import sqlite3          # 換成 psycopg、pymysql 等驅動,流程相同

conn = sqlite3.connect("example.db")   # 1. 建立連線
cur = conn.cursor()                    # 2. 取得 cursor

cur.execute("SELECT name, age FROM users WHERE age > ?", (20,))  # 3. 執行 SQL
rows = cur.fetchall()                  # 4. 取得結果

cur.execute("INSERT INTO users (name, age) VALUES (?, ?)", ("Eve", 22))
conn.commit()                          # 5. 寫入後提交交易

cur.close()                            # 6. 關閉 cursor 與連線
conn.close()
物件/方法 作用
connect() 建立連線,參數依驅動而異
cursor() 建立游標,用來執行 SQL 與讀取結果
execute(sql, params) 執行一條 SQL,params 為 tuple 或 dict
executemany(sql, seq) 以多組參數重複執行,常用於批次新增
fetchone() / fetchmany(n) / fetchall() 取一筆/取 n 筆/取全部
commit() / rollback() 提交/取消目前交易
rowcount / lastrowid 受影響筆數/最後新增的 id

參數化查詢與 SQL 注入

SQL 注入(SQL Injection)是最常見的資料庫安全漏洞:程式把使用者輸入直接拼進 SQL 字串,攻擊者就能輸入特殊字元竄改 SQL 的意思。

name = "x' OR '1'='1"

# ❌ 危險:字串拼接,WHERE 條件變成永遠成立,會撈出所有資料
cur.execute(f"SELECT * FROM users WHERE name = '{name}'")

# ✅ 安全:參數化查詢,驅動會把 name 當成「值」而不是 SQL
cur.execute("SELECT * FROM users WHERE name = ?", (name,))

各驅動的佔位符(paramstyle)不同,這是換資料庫時最常需要修改的地方:

驅動 佔位符 範例
sqlite3 ? 或 :name WHERE id = ?
psycopg / psycopg2 %s 或 %(name)s WHERE id = %s
PyMySQL / mysql-connector-python %s 或 %(name)s WHERE id = %s

佔位符只能代表「值」

資料表名稱、欄位名稱、ORDER BY 方向等 SQL 結構不能用佔位符。若必須動態指定,請用白名單檢查(例如 if column not in {"name", "age"}: raise ValueError),或改用 SQLAlchemy 組查詢。

交易:commit 與 rollback

DB-API 預設在第一條修改資料的 SQL 執行時自動開始交易,直到呼叫 commit() 才會真正寫入。發生錯誤時應呼叫 rollback() 取消整組操作,保持資料一致:

try:
    cur.execute("UPDATE accounts SET balance = balance - ? WHERE id = ?", (100, 1))
    cur.execute("UPDATE accounts SET balance = balance + ? WHERE id = ?", (100, 2))
    conn.commit()
except Exception:
    conn.rollback()
    raise

多數驅動的連線物件支援 with conn:,效果等同上面的 try/commit/rollback(各驅動是否同時關閉連線略有不同,請參考各資料庫頁面)。

不要把密碼寫死在程式裡

連線資訊建議放在環境變數或 .env 檔,並將 .env 加入 .gitignore,避免密碼被推上 GitHub:

import os
import psycopg

conn = psycopg.connect(os.environ["DATABASE_URL"])
# DATABASE_URL 例如:postgresql://app_user:app_password@localhost:5432/app_db

搭配 pandas 做資料分析

pandas 可以把查詢結果直接讀成 DataFrame,也能把 DataFrame 寫回資料表。SQLite 可直接傳入連線物件;其他資料庫建議傳入 SQLAlchemy 的 engine:

import sqlite3
import pandas as pd

with sqlite3.connect("example.db") as conn:
    df = pd.read_sql("SELECT * FROM users WHERE age > ?", conn, params=(20,))
    print(df.describe())

    df.to_sql("users_backup", conn, if_exists="replace", index=False)

推薦影音

Python Tutorial: Psycopg2 for Beginners(Ferds the NetDev)

簡述:示範用 psycopg2 連線 PostgreSQL、建立 cursor、執行參數化查詢與提交交易,流程與本頁介紹的 DB-API 標準流程一致,換成其他驅動也適用。

相關資料