Python 3.x 環境下 MySQLdb (即 mysql-python) 已停止維護、不支援 Python 3。官方推薦遷移至 PyMySQL,純 Python 實現、API 高度相容、支援 Python 3.4+。本文提供從安裝、連線、游標操作到異常處理的完整範例。
# 方法 1:GitHub 源碼安裝 git clone https://github.com/PyMySQL/PyMySQL.git cd PyMySQL python setup.py install # 方法 2:pip 安裝(推薦) pip install PyMySQL
| MySQLdb | PyMySQL | 備註 |
|---|---|---|
import MySQLdb | import pymysql | |
MySQLdb.connect(...) | pymysql.connect(...) | 參數名一致:host/user/passwd/db/port/charset |
cursor() | cursor() | 預設回傳元組,建議 cursorclass=pymysql.cursors.DictCursor |
execute() | execute() | 參數化查詢用 %s 佔位符(非 ?) |
fetchone()/fetchall() | fetchone()/fetchall() | |
conn.commit()/rollback() | conn.commit()/rollback() | |
conn.close() | conn.close() |
import pymysql
from pymysql import MySQLError
def query_users():
conn = None
try:
# 建立連線,指定字元集 utf8mb4、字典游標
conn = pymysql.connect(
host='localhost',
user='root',
password='qin',
db='person',
port=3306,
charset='utf8mb4',
cursorclass=pymysql.cursors.DictCursor
)
with conn.cursor() as cursor:
sql = "SELECT id, name, sex FROM person WHERE id > %s"
cursor.execute(sql, (0,)) # 參數化,防注入
rows = cursor.fetchall()
for row in rows:
# DictCursor 回傳 dict,直接用鍵存取
print(f"ID: {row['id']} 名字: {row['name']} 性別: {row['sex']}")
except MySQLError as e:
print(f"資料庫錯誤: {e}")
except Exception as e:
print(f"未知錯誤: {e}")
finally:
if conn:
conn.close()
if __name__ == '__main__':
query_users()
%s:PyMySQL 不支援 ?,所有型別(含數字、日期)皆用 %s,驅動層自動轉義。utf8mb4:utf8 實為 utf8mb3,不支援 Emoji 與補充字符。pymysql.MySQLError 為基類,具體有 OperationalError、ProgrammingError、IntegrityError 等。DBUtils.PooledDB 或 SQLAlchemy Engine 使用,避免頻繁建連開銷。eventlet.monkey_patch() 或 gevent 可實現非阻塞 IO,OpenStack 生產驗證通過。python -c "import pymysql; print(pymysql.__version__)"
結語:PyMySQL 是 Python 3 連接 MySQL 的標準選擇之一,API 與 MySQLdb 高度相容,遷移成本極低。掌握「字典游標、參數化查詢、utf8mb4、連線池」四要素,即可編寫健壯、安全、高效的資料庫存取代碼。