Python使用Mysql連接池

0X00 爲什麼要用數據庫連接池

平常可能習慣使用pymysql或者一些數據庫連接包去跟數據庫交互,代碼可能是這樣的:

import pymysql

config = {
    'host': config_template['MYSQL']['HOST'],
    'port': config_template['MYSQL']['PORT'],
    'user': config_template['MYSQL']['USER'],
    'password': config_template['MYSQL']['PASSWD'],
    'db': config_template['MYSQL']['DB'],
    'charset': config_template['MYSQL']['CHARSET'],
    'cursorclass': pymysql.cursors.DictCursor
}

def db_conn():
    conn = pymysql.connect(**config)
    cursor = conn.cursor()
    return conn,cursor

大概就是這麼個意思,將連接數據庫封裝爲一個方法,每次需要連接的時候調用該方法獲取conn和cursor對象,但是這樣會有損耗,因爲每次都需要 建立連接->執行數據庫操作->釋放連接。而數據庫連接池爲維護一個保存有多個數據庫連接的池子,每次需要連接數據庫時,從連接池中取出一個連接進行使用即可,使用完畢後連接不會釋放,而是歸還給連接池進行管理,節省了不斷建立連接和釋放連接的過程。

0X01 使用DBUtils建立數據庫連接池

import pymysql
from g_conf.config import config_template
from DBUtils.PooledDB import PooledDB


class MysqlPool:
    config = {
        'creator': pymysql,
        'host': config_template['MYSQL']['HOST'],
        'port': config_template['MYSQL']['PORT'],
        'user': config_template['MYSQL']['USER'],
        'password': config_template['MYSQL']['PASSWD'],
        'db': config_template['MYSQL']['DB'],
        'charset': config_template['MYSQL']['CHARSET'],
        'maxconnections': 70, # 連接池最大連接數量
        'cursorclass': pymysql.cursors.DictCursor
    }
    pool = PooledDB(**config)

    def __enter__(self):
        self.conn = MysqlPool.pool.connection()
        self.cursor = self.conn.cursor()
        return self

    def __exit__(self, type, value, trace):
        self.cursor.close()
        self.conn.close()

可以看到,通過DBUtils,實例化一個PooledDB對象作爲MysqlPool類的類屬性,通過重寫__enter__和__exit__方法讓我們在進入with語句時從連接池中獲取到數據庫連接,在with語句結束後,自動釋放連接池,歸還給連接池。

使用方式與普通連接mysql並無區別,使用with語句調用即可:

def func(tar_id):
    with MysqlPool() as db:
        db.cursor.execute('YOUR_SQL')
        db.conn.commit()

裝飾器用法:

def db_conn(func):
    def wrapper(*args, **kw):
        with MysqlPool() as db:
            result = func(db, *args, **kw)
        return result
    return wrapper

@db_conn
def update_info(db, *args, **kw):
    try:
        db.cursor.execute("YOUR_SQL")
        db.conn.commit()
        return 0
    except Exception as e:
        db.conn.rollback()
        return 1

DBUtils還有很多強大的功能,如果有更多的需求可以自行查閱相關文檔,本文僅僅是拋磚引玉,提供一種數據庫連接池的使用方法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章