新手指南:Python 與 PostgreSQL 的強力橋樑——psycopg 驅動程式
更新日期: 2025 年 3 月 29 日
本文為 Django 連接 PostgreSQL 基學教學,第 1 篇:
- 新手指南:Python 與 PostgreSQL 的強力橋樑——psycopg 驅動程式 👈 所在位置
- 新手指南:Django 與 PostgreSQL 的資料庫設定與密碼管理
在開發 Python 應用程式時,經常需要與資料庫互動,而 PostgreSQL 是一個功能強大的關係型資料庫管理系統。
為了讓 Python 能夠高效地與 PostgreSQL 資料庫進行溝通,我們需要一個專用的驅動程式——psycopg
。
本篇文章將帶您了解 psycopg 的基本概念、如何與 Django 整合,並提供實際操作範例,幫助您快速上手。
psycopg 是什麼?
概念簡介
psycopg
是 Python 與 PostgreSQL 互動的驅動程式,提供穩定且高效能的方式來連接和操作資料庫。
主要功能
- 支援執行各類 SQL 查詢(如
SELECT
、INSERT
)。 - 支援 PostgreSQL 的進階功能,包括事務管理、JSON 資料類型、陣列操作和游標(Cursor)。
- 適合多執行緒環境,為高效能應用程式提供支持。
目前最新版本為 psycopg3
,它是 psycopg2
的升級版,支援更多現代化功能(如非同步操作)。
Django 與 PostgreSQL 的連接
Django 是一個高效能的 Python 網頁框架,內建 ORM(物件關聯映射),能讓開發者以 Python 語法操作資料庫。
Django 預設透過 psycopg 驅動程式與 PostgreSQL 進行連接。
安裝 psycopg 驅動程式
在您的開發環境中安裝 psycopg。可以選擇安裝 psycopg2
或更新的 psycopg3
:
# 安裝 psycopg2
pip install psycopg2
# 或安裝 psycopg3
pip install "psycopg[binary]"
配置 Django 的資料庫設定
在 Django 專案的 settings.py
文件中,設定 PostgreSQL 資料庫的連接資訊:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql', # 使用 PostgreSQL 驅動程式
'NAME': 'your_database_name', # 資料庫名稱
'USER': 'your_database_user', # 使用者名稱
'PASSWORD': 'your_password', # 密碼
'HOST': 'localhost', # 資料庫伺服器位置
'PORT': '5432', # 資料庫埠號(默認為 5432)
}
}
測試連接
檢查 Django 是否成功連接到資料庫:
- 遷移資料庫結構
執行以下命令,確保 Django 的內建資料表(如auth_user
)被正確建立:python manage.py migrate
- 啟動伺服器測試應用
如果能正常啟動伺服器並運行,表示 Django 已成功連接到 PostgreSQL。
使用 ORM 操作資料庫
Django 的 ORM 提供高效的資料庫操作功能,以下是基本範例:
插入資料
from myapp.models import MyModel
# 插入一筆資料
MyModel.objects.create(name="Example", value=42)
查詢資料
# 查詢資料
records = MyModel.objects.filter(value=42)
print(records)
psycopg 的運作方式
當 Django 與 PostgreSQL 互動時,psycopg
作為核心驅動程式,負責處理從高層的 Django ORM 到低層資料庫之間的溝通。
以下是更詳細的解釋這個運作流程的幾個關鍵點:
選擇 PostgreSQL 引擎
- 在 Django 的設定檔(
settings.py
)中,透過將ENGINE
設定為'django.db.backends.postgresql'
,指定要使用 PostgreSQL 作為資料庫後端。 - 這時,Django 會自動使用
psycopg
作為 PostgreSQL 的 Python 驅動程式,因為它是官方推薦且與 Django 完美整合的套件。
Django ORM 的 SQL 語句生成
- 當開發者在程式中執行 ORM 操作時(例如
Model.objects.filter()
或Model.objects.create()
),Django ORM 負責將這些高階 Python 方法轉換成相應的 SQL 查詢語句。 - 舉例來說:
# 假設有一個名為 Book 的模型
Book.objects.filter(title="Django")
- Django ORM 會生成類似這樣的 SQL:
SELECT * FROM book WHERE title = 'Django';
透過 psycopg 與資料庫溝通
psycopg
在這個階段負責接收來自 Django 的 SQL 語句,並透過 PostgreSQL 的協議,將 SQL 傳送到資料庫伺服器執行。- 它處理低層次的通訊細節,例如:
- 開啟連線(Connection)
- 傳送查詢
- 管理交易(Transaction,包含 COMMIT 或 ROLLBACK)
- 傳遞參數化查詢以避免 SQL Injection(SQL 注入)。
- 舉例:
cursor.execute("SELECT * FROM book WHERE title = %s", ["Django"])
這裡的 %s
是一種參數佔位符,psycopg
負責正確插入引數,確保安全性。
補充:什麼是「交易」?
在資料庫中,交易(Transaction) 是一組操作的集合,這些操作作為一個整體被執行。
這裡有兩個關鍵的原則:
- 要麼全部成功,要麼全部失敗(All or nothing)。
- 保證資料的一致性和完整性。
舉個簡單例子: 假設你在一個銀行系統中要進行「轉帳」操作:
- 從帳戶 A 減少 $100。
- 將 $100 增加到帳戶 B。
這兩個步驟應該被視為一個整體:
- 如果第一步成功,但第二步失敗(例如系統崩潰),就會出現問題,帳戶 A 的錢被扣了,但帳戶 B 沒有收到,這會導致資料不一致。
透過交易,我們可以確保這兩步要麼都完成(成功),要麼都回滾(失敗)。
COMMIT 和 ROLLBACK 是什麼?
交易管理主要有兩個重要指令:
- COMMIT:確認所有操作成功,將這些改變保存到資料庫。
- ROLLBACK:如果某些操作出現問題,取消所有尚未保存的改變,資料庫恢復到操作前的狀態。
為什麼交易很重要?
交易確保資料庫操作的可靠性和一致性,特別是在多步驟操作中,防止資料庫進入不一致的狀態。
例如:
- 電商系統:訂單生成、庫存扣減、付款確認需要統一處理。
- 金融系統:處理轉帳、記錄歷史交易。
在 Django 和 psycopg 裡,交易怎麼運作?
- 當你進行資料庫操作(如
save()
或update()
)時,Django 通常會自動管理交易。- 如果需要執行多個步驟且需要手動管理,Django 提供了
transaction.atomic()
工具,讓你能確保多個操作要麼一起成功,要麼一起失敗。例子:銀行轉帳的交易流程
假設你寫了一段程式模擬轉帳操作:
from django.db import transaction try: with transaction.atomic(): # 開啟一個交易 # 減少帳戶 A 的餘額 account_a.balance -= 100 account_a.save() # 增加帳戶 B 的餘額 account_b.balance += 100 account_b.save() # 如果這裡一切成功,Django 會自動執行 COMMIT except Exception as e: # 如果任何一個操作失敗,Django 會執行 ROLLBACK print("交易失敗!", e)
- 如果 兩個步驟都成功:
- Django 會執行 COMMIT,將這些改變永久保存到資料庫中。
- 如果 任何一個步驟失敗(例如帳戶 B 不存在):
- Django 會執行 ROLLBACK,撤銷所有已經進行的操作(如還原帳戶 A 的餘額)。
以下用圖解來幫助理解交易流程:
1. 開始交易 (Transaction) ├── 減少帳戶 A 的餘額 ├── 增加帳戶 B 的餘額 ├── 檢查是否成功 ├── 全部成功 -> COMMIT -> 資料保存到資料庫 └── 失敗 -> ROLLBACK -> 資料回到最初狀態
補充:什麼是 SQL Injection(SQL 注入)?
SQL Injection 是一種常見的攻擊方式,攻擊者透過在輸入中,插入惡意的 SQL 語句來操控你的資料庫。
這種攻擊可能會:
- 獲取敏感資料。
- 刪除或修改資料庫中的內容。
- 甚至完全摧毀資料庫。
舉例: 假設你有一個登入系統,使用者輸入帳號和密碼。後端程式執行類似這樣的查詢:
SELECT * FROM users WHERE username = 'user_input' AND password = 'user_password';
如果使用者的輸入如下:
username
:admin
password
:' OR '1'='1
這時,生成的 SQL 會變成:
SELECT * FROM users WHERE username = 'admin' AND password = '' OR '1'='1';
這條語句總是成立,因為
1='1'
永遠為真。攻擊者因此可以繞過登入檢查,取得未經授權的存取。什麼是參數化查詢?
參數化查詢 是一種安全的處理方式,可以避免 SQL Injection。
它的核心是:
- 將使用者輸入的資料和 SQL 語句分開處理。
- 使用佔位符(placeholder)來插入參數,讓資料庫將參數視為純資料而非 SQL 指令。
怎麼用參數化查詢避免 SQL Injection?
在 Django 中,透過
psycopg
驅動程式,參數化查詢可以輕鬆實現。例子: 我們有一個查詢要檢查使用者的帳號和密碼:
不安全的方式(容易被注入攻擊)
username = "admin" password = "' OR '1'='1" query = f"SELECT * FROM users WHERE username = '{username}' AND password = '{password}';" cursor.execute(query)
上述程式會生成一個不安全的查詢:
SELECT * FROM users WHERE username = 'admin' AND password = '' OR '1'='1';
攻擊者可能輕鬆利用這個漏洞。
安全的方式:參數化查詢
使用參數化查詢,將資料與查詢分開處理,惡意輸入將不會被解釋為 SQL 指令。例如:
query = "SELECT * FROM users WHERE username = %s AND password = %s;" cursor.execute(query, [username, password])
這裡的
%s
是一個佔位符(placeholder),psycopg
會將username
和password
的值正確地插入查詢,確保它們只是普通的文字。假設
username="admin"
,password="' OR '1'='1"
,最終執行的查詢是:SELECT * FROM users WHERE username = 'admin' AND password = '\' OR \'1\'=\'1';
Django ORM 的自動防護
在 Django 的 ORM 中,參數化查詢是內建的功能,ORM 會自動幫你處理參數,預防 SQL Injection。
範例: 假設你要查詢特定使用者:
User.objects.filter(username="admin", password="' OR '1'='1'")
Django 會自動生成安全的 SQL 查詢,效果類似這樣:
SELECT * FROM users WHERE username = 'admin' AND password = '\' OR \'1\'=\'1';
圖解參數化查詢的作用
以下用圖解幫助你理解:
不安全的查詢: User Input (惡意 SQL) --> 拼接成整條 SQL 查詢 --> 攻擊成功 參數化查詢: User Input (惡意 SQL) --> 傳遞作為純資料 --> 無法改變查詢邏輯
PostgreSQL 執行查詢
- 當 SQL 語句到達 PostgreSQL 後,資料庫引擎負責執行該查詢,並根據請求返回結果。
- 假如查詢是一個
SELECT
操作,PostgreSQL 會返回查詢結果(如資料表中的列和行);如果是更新或刪除操作,則返回影響的行數。
處理返回資料
psycopg
負責接收來自 PostgreSQL 的回應結果,並將其轉換為 Python 可處理的資料格式。- 舉例:
- 如果 PostgreSQL 返回一個資料列,
psycopg
會將其轉換為 Python 的tuple
或dict
。 - 例如,從資料庫取出的值
[1, "Django"]
,可能會以 Python 的結構形式返回:(1, "Django")
- 如果 PostgreSQL 返回一個資料列,
Django 封裝資料
- 接收到
psycopg
傳回的資料後,Django 會將其進一步處理,封裝為高層次的 Python 資料結構。 - 如果查詢是基於 Django 模型(Model)的,返回的結果會是一組 ORM 物件:
books = Book.objects.filter(title="Django") for book in books: print(book.title)
- 這些 ORM 物件讓開發者可以使用熟悉的 Python 方法與資料互動,而不需要直接處理底層 SQL。
核心角色:
- Django ORM:負責生成 SQL 語句,並將高階 Python 語法轉換為資料庫可執行的查詢。
- psycopg:負責 Django 與 PostgreSQL 之間的溝通橋樑,執行 SQL 語句並處理資料庫協議。
- PostgreSQL:資料實際存取的核心,執行查詢並返回結果。
這樣的分工讓開發者能專注於高階業務邏輯,而不需深究底層資料庫操作,進一步提高了開發效率與程式的可維護性。
psycopg3 的進階特性
psycopg3
是 psycopg2
的升級版本,具備以下優勢:
- 非同步操作:適合高併發應用。
- 靈活配置:可根據需求進行擴展。
- 與 psycopg2 相容:易於遷移現有專案。
如果您的應用需要高效能或非同步支援,可以考慮使用 psycopg3
:
pip install "psycopg[binary]"
總結
psycopg
是 Python 與 PostgreSQL 之間的橋樑,提供高效穩定的資料庫操作能力。- Django 利用 psycopg 作為驅動程式,讓開發者能通過 ORM 以簡單方式操作資料庫。
- 使用步驟:
- 安裝 psycopg 驅動程式。
- 配置
settings.py
資料庫連接。 - 測試連接並開始操作資料庫。
如果您需要更高效的操作,可考慮使用 psycopg3
。
透過 psycopg,Python 與 PostgreSQL 的整合變得簡單高效,是開發現代應用程式的首選工具之一!