在 psycopg2
中,驗證數據庫連接是否有效(即連接是否仍然活躍)可以通過以下幾種方法實現:
1. 使用 conn.closed
屬性
psycopg2
的連接對象有一個 closed
屬性,可以檢查連接是否已關閉:
import psycopg2conn = psycopg2.connect(host="localhost",database="testdb",user="postgres",password="your_password"
)# 檢查連接是否關閉
if conn.closed:print("連接已關閉")
else:print("連接仍然有效")conn.close()
問題:closed
只能檢測連接是否被顯式關閉,無法檢測連接是否因網絡問題或數據庫超時而失效。
2. 執行簡單查詢(推薦)
最可靠的方法是 執行一個簡單的 SQL 查詢(如 SELECT 1
),如果查詢失敗,則說明連接已斷開:
def is_connection_valid(conn):try:cursor = conn.cursor()cursor.execute("SELECT 1") # 執行簡單查詢cursor.fetchone() # 獲取結果(可選)cursor.close()return True # 查詢成功,連接有效except (psycopg2.Error, psycopg2.OperationalError):return False # 查詢失敗,連接已斷開# 使用示例
if is_connection_valid(conn):print("連接有效")
else:print("連接已斷開,需要重新連接")conn = psycopg2.connect(...) # 重新建立連接
優點:
- 能檢測 網絡中斷、數據庫超時、連接被服務器關閉 等情況。
- 適用于連接池(如
ThreadedConnectionPool
)中的連接健康檢查。
3. 使用 conn.poll()
方法(適用于異步檢查)
psycopg2
提供了 conn.poll()
方法,可以檢查連接狀態:
def is_connection_valid(conn):try:conn.poll() # 檢查連接狀態return Trueexcept psycopg2.OperationalError:return False
說明:
poll()
會返回連接狀態(如psycopg2.extensions.POLL_OK
、POLL_ERROR
等)。- 但通常直接捕獲異常更簡單。
4. 在連接池中驗證連接
如果使用 ThreadedConnectionPool
,可以在 getconn()
后驗證連接是否有效,如果無效則重新創建:
from psycopg2 import OperationalErrordef get_valid_connection(pool):conn = pool.getconn()if not is_connection_valid(conn): # 使用前面的方法檢查conn.close() # 關閉無效連接conn = pool.getconn() # 嘗試獲取新連接return conn# 使用示例
conn = get_valid_connection(pool)
5. 設置 keepalives
參數(預防連接斷開)
在連接字符串中設置 keepalives
參數,讓 PostgreSQL 服務器定期發送心跳包,防止連接因空閑超時而斷開:
conn = psycopg2.connect(host="localhost",database="testdb",user="postgres",password="your_password",keepalives=1, # 啟用 TCP keepalivekeepalives_idle=30, # 30秒空閑后發送心跳keepalives_interval=10, # 每10秒發送一次心跳keepalives_count=5 # 最多嘗試5次
)
適用場景:
- 適用于長時間空閑的連接,減少因網絡問題導致的連接斷開。
總結
方法 | 適用場景 | 備注 |
---|---|---|
conn.closed | 僅檢查連接是否被顯式關閉 | 無法檢測網絡問題 |
執行簡單查詢(SELECT 1 ) | 檢測連接是否真正可用 | 推薦方法 |
conn.poll() | 異步檢查連接狀態 | 較少使用 |
連接池 + 驗證 | 在 ThreadedConnectionPool 中使用 | 確保獲取的連接有效 |
keepalives 參數 | 預防連接因空閑超時斷開 | 適用于長時間空閑連接 |
最佳實踐
- 在獲取連接后,先執行
SELECT 1
驗證連接是否有效。 - 如果連接無效,關閉并重新獲取連接(避免連接池返回壞連接)。
- 設置
keepalives
參數,減少空閑連接被斷開的情況。
這樣能確保你的應用在連接失效時自動恢復,提高穩定性。