← 返回大綱
第十二章

資料庫操作
與 SQL 整合

Database Interaction

概念

資料庫 vs 檔案

存成檔案(JSON/CSV)

  • 簡單,適合小量資料
  • 每次都要讀整個檔案
  • 難以查詢特定資料
  • 多人同時寫入容易出問題

使用資料庫

  • 大量資料也能快速查詢
  • 支援複雜的查詢條件
  • 交易機制保證資料一致性
  • 多人同時操作不衝突
本章使用 SQLite

SQLite 是 Python 內建的輕量資料庫,不需要額外安裝,非常適合入門學習。

SQL 基礎

SQL 基本語法

操作SQL 語法
建立資料表CREATE TABLE students (...)
新增資料INSERT INTO students VALUES (...)
查詢資料SELECT * FROM students
條件查詢SELECT * FROM students WHERE age > 18
更新資料UPDATE students SET score=90 WHERE id=1
刪除資料DELETE FROM students WHERE id=1
sqlite3

SQLite3 基本操作

import sqlite3

# 連線(檔案不存在會自動建立)
conn = sqlite3.connect("school.db")
cursor = conn.cursor()

# 建立資料表
cursor.execute("""
    CREATE TABLE IF NOT EXISTS students (
        id     INTEGER PRIMARY KEY AUTOINCREMENT,
        name   TEXT    NOT NULL,
        age    INTEGER,
        score  REAL
    )
""")

# 儲存變更
conn.commit()
conn.close()
sqlite3

新增、查詢資料

conn = sqlite3.connect("school.db")
cursor = conn.cursor()

# 新增一筆
cursor.execute("INSERT INTO students (name, age, score) VALUES (?, ?, ?)",
               ("Ian", 18, 95))

# 批次新增
students = [("Alice", 17, 88), ("Bob", 19, 72)]
cursor.executemany("INSERT INTO students (name, age, score) VALUES (?, ?, ?)",
                   students)
conn.commit()

# 查詢所有
cursor.execute("SELECT * FROM students")
rows = cursor.fetchall()
for row in rows:
    print(row)   # (1, 'Ian', 18, 95.0)

conn.close()
sqlite3

條件查詢與更新

conn = sqlite3.connect("school.db")
cursor = conn.cursor()

# 條件查詢
cursor.execute("SELECT name, score FROM students WHERE score >= 80 ORDER BY score DESC")
for name, score in cursor.fetchall():
    print(f"{name}: {score}")

# 更新
cursor.execute("UPDATE students SET score = ? WHERE name = ?", (100, "Ian"))

# 刪除
cursor.execute("DELETE FROM students WHERE score < 60")

conn.commit()
conn.close()
with 語法

推薦用法:with 語法

import sqlite3

def get_top_students(db_path, limit=3):
    with sqlite3.connect(db_path) as conn:
        conn.row_factory = sqlite3.Row   # 讓結果可以用欄位名存取
        cursor = conn.cursor()
        cursor.execute(
            "SELECT name, score FROM students ORDER BY score DESC LIMIT ?",
            (limit,)
        )
        return [dict(row) for row in cursor.fetchall()]

top = get_top_students("school.db")
for s in top:
    print(f"{s['name']}: {s['score']}")
with 語法的好處

自動 commit 或 rollback,不需要手動 conn.close()

實作練習

動手試試看

import sqlite3

def init_db():
    with sqlite3.connect("todo.db") as conn:
        conn.execute("""CREATE TABLE IF NOT EXISTS todos (
            id   INTEGER PRIMARY KEY AUTOINCREMENT,
            task TEXT    NOT NULL,
            done INTEGER DEFAULT 0
        )""")

def add_todo(task):
    with sqlite3.connect("todo.db") as conn:
        conn.execute("INSERT INTO todos (task) VALUES (?)", (task,))

def list_todos():
    with sqlite3.connect("todo.db") as conn:
        rows = conn.execute("SELECT id, task, done FROM todos").fetchall()
        for id, task, done in rows:
            status = "✓" if done else "○"
            print(f"{status} [{id}] {task}")

init_db()
add_todo("學 Python")
add_todo("完成作業")
list_todos()

第十二章完成!

學會了 SQLite3 的 CRUD 操作與 SQL 基本語法。