本文由簡體中文內容自動轉碼而成。阿里雲不保證此自動轉碼的準確性、完整性及時效性。本文内容請以簡體中文版本為準。

使用Python串連池DBUtils串連資料庫

更新時間:2024-10-16 19:24

如果您的應用側主要使用Python語言,且資料庫連接建立頻繁(例如短串連情境)或串連數量較大(大於MySQL資料庫的串連數限制),您可以使用Python串連池DBUtils串連資料庫,降低串連建立頻率以減少資料庫主線程的開銷。

前提條件

  • 應用伺服器已安裝Python環境且Python版本在3.7至3.12。

  • 已將伺服器IP地址添加至RDS執行個體白名單中,詳情請參見設定IP白名單

    說明

    若您的應用程式部署在阿里雲ECS伺服器上,且ECS與RDS已實現內網互連(ECS與RDS執行個體的地區、VPC均相同),則無需設定IP白名單。

準備工作

  • 安裝DBUtils:您需要通過以下命令在伺服器上安裝Python串連池DBUtils,本教程中DBUtils版本為3.1.0,更多版本及資訊請參見DBUtils

    pip install DBUtils==3.1.0
  • 安裝PyMySQL:您需要通過以下命令安裝PyMySQL,以支援伺服器串連資料庫。

    pip install pymysql

使用DBUtils串連資料庫

  1. 匯入相關模組:在使用DBUtils串連資料庫前,您需要通過以下代碼匯入相關模組。

    from dbutils.pooled_db import PooledDB
    import importlib
    import pymysql
  2. 構建DBUtilsDemo:為了方便您後續的方法調用與管理,建議您建立一個DBUtilsDemo類,在__init__方法中設定串連池參數,並向該類中添加_connect_close方法以便從串連池中擷取與歸還資料庫連接。

    class DBUtilsDemo:
        def __init__(self, url, user, password, database):
            db_config = {
                "host": url,
                "port": 3306,
                "user": user,
                "db": database,
                "password": password,
                "charset": "utf8",
                "connect_timeout": 3,
                "read_timeout": 10,
                "write_timeout": 10
            }
            '''
              DBUtils串連池常見參數的詳細說明請參見後文,以下為參數簡要說明:
                mincached: 池中閑置串連的初始數量(0表示啟動時不會建立串連)。
                maxcached: 池中閑置串連的最大數量(0或None表示串連池大小沒有限制)。
                maxshared: 共用串連的最大數量(0或None表示所有串連都是專用的)。
                maxconnections: 一般允許的最大串連數量(0或None表示串連不受限制)。
                blocking: 在超過最大串連數量時的行為。
                maxusage: 單個串連的最大重用次數(0或None表示無限重用)。
            '''
            self.pooled = PooledDB(pymysql, maxcached=20, maxshared=0, maxconnections=100, maxusage=20, **db_config)
    
        # 從串連池擷取串連
        def _connect(self):
            try:
                r = self.pooled.connection()
                return r
            except Exception as e:
                print("Failed to connect:" + str(e))
    
        # 歸還串連到串連池
        def _close(self, conn, stmt):
            if stmt:
                stmt.close()
            if conn:
                conn.close()
  3. __main__函數中初始化DBUtilsDemo類並串連資料庫:DBUtilsDemo類構造完成後,您可以在__main__函數中初始化該類,並擷取資料庫連接。

    if __name__ == '__main__':
        # RDS MySQL執行個體串連地址,需要根據伺服器情況選擇RDS內網/外網串連地址。
        url = 'rm-bp**************.mysql.rds.aliyuncs.com'
        # 使用者名稱,根據實際情況做替換。
        user = 'dbuser'
        # 密碼,根據實際情況做替換。
        password = '****'
        # 串連的資料庫名稱,根據實際情況做替換。
        database = 'dbtest'
    
        # 擷取串連池對象
        poolUtils = DBUtilsDemo(url, user, password, database)

串連池常見參數配置

在使用DBUtils串連資料庫時,建議您根據下述內容為串連池設定合適的參數(在__init__方法調用的PooledDB函數中設定),使資料庫的運行更穩定高效。

重要

為了最大程度地避免潛在的風險和不確定性,在將新的參數值用於生產環境前,建議您至少進行一輪完整的功能測試和效能測試,以確保系統穩定性和可靠性。

推薦配置的參數
可選擇配置的參數
保持預設配置的參數

推薦您在使用DBUtils串連池時設定以下參數,降低資料庫運行風險。

參數名

含義

預設值

推薦值

說明

maxcached

池中閑置串連的最大數量。

0

20

  • 0或None表示串連池大小沒有限制。

  • 適當配置該參數可以預留一定數量的串連,快速處理突發的資料庫請求。

maxusage

單個串連的最大重用次數。

None

10~20

  • 0或None表示無限重用,當達到串連的最大重用次數時,串連將自動重設(關閉並重新開啟)。

  • 適當配置該參數可以防止空閑串連一直存活佔用資源。

  • 建議根據應用程式的實際需求以及資料庫的處理能力決定該參數配置。

connect_timeout

串連到資料庫的逾時時間()。

10

3

  • 最小值1,最大值31536000

  • 建議設定1~10秒之間,取決於網路品質高低,以及應用端與服務端的距離。

read_timeout

從資料庫讀取的逾時時間()。

None

10~60

  • 預設值None表示沒有逾時限制。

  • 該參數不宜設定過短。針對讀取SQL執行時間明顯過長而導致逾時的問題,應當首先檢查SQL或者資料庫本身,而不是優先調整該參數。

write_timeout

寫入資料庫的逾時時間()。

None

10~60

  • 預設值None表示沒有逾時限制。

  • 該參數不宜設定過短。針對寫入SQL執行時間明顯過長而導致逾時的問題,應當首先檢查SQL或者資料庫本身,而不是優先調整該參數。

使用DBUtils串連池時,您可以選擇性地配置以下參數,提升資料庫效能。

參數名

含義

預設值

推薦值

說明

maxconnections

串連池允許的最大串連數量。

0

100

  • 0或None表示串連不受限制。

  • 需要根據資料庫的並發處理能力和負載情況來合理設定該值。

  • 通常情況下,建議將該值設定為資料庫能夠同時處理的最大串連數。

對於以下常見的串連池參數,您可以選擇直接使用預設配置或根據自身需求調整參數。

參數名

含義

預設值

推薦值

說明

mincached

池中閑置串連的初始數量。

0

/

  • 0表示啟動時不會建立串連。

  • 推薦預設配置,即啟動時不建立串連,等需要使用時再建立。

maxshared

共用串連的最大數量。

0

/

  • 0或None表示所有串連都是專用的。

  • 當到達最大數量時,如果串連已經被聲明為可共用,則保持可共用不變。

blocking

超過最大串連數量時的處理方法。

False

/

  • 設定為True時,會阻塞等待直到串連數減少。

  • 設定為False時,資料庫會報告錯誤。

setsession

串連被建立時執行的 SQL 陳述式

None

/

該參數可以用來設定會話層級的參數或者執行其他初始化操作。

reset

串連被放回串連池時,是否需要重設串連狀態。

True

/

  • 設定為True時,表示需要重設。

  • 設定為False時,表示不需要重設。

failures

資料庫連接失敗時的重連次數。

None

/

/

ping

串連池在空閑串連時執行的心跳檢測操作。

1

/

該參數用來驗證串連可用性。

後續資料庫操作

您可以在DBUtilsDemo類中添加自訂方法處理讀寫請求,滿足對資料庫的操作需求。

讀請求處理
寫請求處理

1. 添加自訂方法

您需要在DBUtilsDemo類中添加自訂方法處理資料庫讀請求,本文以查詢單條記錄與查詢多條記錄為例。

  • 查詢單條記錄

    def select_row(self, sql):
        connection = self._connect()
        statement = None
        try:
            statement = connection.cursor()
            statement.execute(sql)
            row = statement.fetchone()
            return row
        except Exception as e:
            print(e)
        finally:
            self._close(connection, statement)
  • 查詢多條記錄

    def select_rows(self, sql):
        connection = self._connect()
        statement = None
        try:
            statement = connection.cursor()
            statement.execute(sql)
            rows = statement.fetchall()
            return rows
        except Exception as e:
            print(e)
        finally:
            self._close(connection, statement)

2. 調用自訂方法

您需要在__main__函數中調用該方法進行資料查詢。

if __name__ == '__main__':
    # 配置串連參數並串連資料庫
    url = 'rm-bp**************.mysql.rds.aliyuncs.com'
    user = 'dbuser'
    password = '****'
    database = 'dbtest'
    poolUtils = DBUtilsDemo(url, user, password, database)

    # 查詢單條記錄
    row = poolUtils.select_row("select * from tb where id = 'i001' limit 1")
    print(row)

    # 查詢多條記錄
    rows = poolUtils.select_rows("select * from tb")
    print(rows)

1. 添加自訂方法

您需要在DBUtilsDemo類中添加自訂方法處理資料庫寫請求(包括INSERTUPDATEDELETECREATE TABLE等命令),本文以帶參數寫請求與不帶參數寫請求為例。

  • 帶參數寫請求處理

    def upsert_data_prams(self, sql_upsert, params):
        connection = self._connect()
        statement = None
        try:
            statement = connection.cursor()
            statement.execute(sql_upsert, params)
            connection.commit()
        except Exception as e:
            print(e)
        finally:
            self._close(connection, statement)
  • 不帶參數寫請求處理

    def upsert_data(self, sql_upsert):
        connection = self._connect()
        statement = None
        try:
            statement = connection.cursor()
            statement.execute(sql_upsert)
            connection.commit()
        except Exception as e:
            print(e)
        finally:
            self._close(connection, statement)

2. 調用自訂方法

您需要在__main__函數中調用該方法執行SQL語句。

if __name__ == '__main__':
    # 配置串連參數並串連資料庫
    url = 'rm-bp**************.mysql.rds.aliyuncs.com'
    user = 'dbuser'
    password = '****'
    database = 'dbtest'
    poolUtils = DBUtilsDemo(url, user, password, database)

    # 不帶參數寫請求處理
    poolUtils.upsert_data("insert into tb(id,name,address) values ('i001','n001','a001')")

    # 帶參數寫請求處理
    params = ['i002', 'n002', 'a002']
    poolUtils.upsert_data_prams("insert into tb(id,name,address) values (%s,%s,%s)", params)

相關文檔

  • 本頁導讀 (1, M)
  • 前提條件
  • 準備工作
  • 使用DBUtils串連資料庫
  • 串連池常見參數配置
  • 後續資料庫操作
  • 相關文檔
文檔反饋