Python學習(二十九)—— pymysql操作數據庫優化


轉載自:http://www.cnblogs.com/liwenzhou/articles/8283687.html

 

我們之前使用pymysql操作數據庫的操作都是寫死在視圖函數中的,並且很多都是重復的代碼。

我們可以優化一下,把重復的代碼提取出來,寫成函數:

import pymysql

# 定義一個數據庫相關的配置項
DB_CONFIG = {
    "host": "127.0.0.1",
    "port": 3306,
    "user": "root",
    "passwd": "root1234",
    "db": "mysite",
    "charset": "utf8"
}


# 查詢多條數據函數
def get_list(sql, args=None):
    conn = pymysql.connect(
        host=DB_CONFIG["host"],
        port=DB_CONFIG["port"],
        user=DB_CONFIG["user"],
        passwd=DB_CONFIG["passwd"],
        db=DB_CONFIG["db"],
        charset=DB_CONFIG["charset"]
    )
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
    cursor.execute(sql, args)
    result = cursor.fetchall()
    cursor.close()
    conn.close()
    return result


# 查詢單條數據函數
def get_one(sql, args=None):
    conn = pymysql.connect(
        host=DB_CONFIG["host"],
        port=DB_CONFIG["port"],
        user=DB_CONFIG["user"],
        passwd=DB_CONFIG["passwd"],
        db=DB_CONFIG["db"],
        charset=DB_CONFIG["charset"]
    )
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
    cursor.execute(sql, args)
    result = cursor.fetchone()
    cursor.close()
    conn.close()
    return result


# 修改記錄
def modify(sql, args=None):
    conn = pymysql.connect(
        host=DB_CONFIG["host"],
        port=DB_CONFIG["port"],
        user=DB_CONFIG["user"],
        passwd=DB_CONFIG["passwd"],
        db=DB_CONFIG["db"],
        charset=DB_CONFIG["charset"]
    )
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
    cursor.execute(sql, args)
    conn.commit()
    cursor.close()
    conn.close()


# 創建記錄
def create(sql, args=None):
    conn = pymysql.connect(
        host=DB_CONFIG["host"],
        port=DB_CONFIG["port"],
        user=DB_CONFIG["user"],
        passwd=DB_CONFIG["passwd"],
        db=DB_CONFIG["db"],
        charset=DB_CONFIG["charset"]
    )
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
    cursor.execute(sql, args)
    conn.commit()
    # 返回剛才創建的那條數據的ID
    last_id = cursor.lastrowid
    cursor.close()
    conn.close()
    return last_id

這樣只要在需要連接數據庫做操作的時候,只需要調用我們上面定義好的函數就可以了。

 

但是這樣還是有問題,當我要大批量創建數據的時候,就需要多次調用create方法了,相當於多次連接多次提交。

可以繼續優化下,把數據庫的連接重用,做到只需一次連接就可執行多次操作。

class SQLManager(object):

    # 初始化實例方法
    def __init__(self):
        self.conn = None
        self.cursor = None
        self.connect()

    # 連接數據庫
    def connect(self):
        self.conn = pymysql.connect(
            host=DB_CONFIG["host"],
            port=DB_CONFIG["port"],
            user=DB_CONFIG["user"],
            passwd=DB_CONFIG["passwd"],
            db=DB_CONFIG["db"],
            charset=DB_CONFIG["charset"]
        )
        self.cursor = self.conn.cursor(cursor=pymysql.cursors.DictCursor)

    # 查詢多條數據
    def get_list(self, sql, args=None):
        self.cursor.execute(sql, args)
        result = self.cursor.fetchall()
        return result

    # 查詢單條數據
    def get_one(self, sql, args=None):
        self.cursor.execute(sql, args)
        result = self.cursor.fetchone()
        return result

    # 執行單條SQL語句
    def moddify(self, sql, args=None):
        self.cursor.execute(sql, args)
        self.conn.commit()

    # 創建單條記錄的語句
    def create(self, sql, args=None):
        self.cursor.execute(sql, args)
        self.conn.commit()
        last_id = self.cursor.lastrowid
        return last_id

    # 關閉數據庫cursor和連接
    def close(self):
        self.cursor.close()
        self.conn.close()

我們把我們數據庫的相關操作都封裝成一個類,在用到的時候,只需要生成一個實例,並對實例調用相應的操作方法就可以了。

db = SQLManager()
class_list = db.get_list("select id, name from class")
teacher_info = db.get_list("SELECT teacher.id, teacher.name, teacher2class.class_id FROM teacher  LEFT JOIN teacher2class ON teacher.id = teacher2class.teacher_id WHERE teacher.id=%s;", [teacher_id])
db.close()

但是,我如果要批量執行多個創建操作,雖然只建立了一次數據庫連接但是還是會多次提交,可不可以改成一次連接,一次提交呢?

可以,只需要用上pymysql的executemany()方法就可以了。

給我們的 SQLManager類添加一個批量執行的 multi_modify()方法就可以了。

# 執行多條SQL語句
def multi_modify(self, sql, args=None):
    self.cursor.executemany(sql, args)
    self.conn.commit()

現在我們如果一次執行多個創建操作的話就可以使用multi_modify()方法,實現一次連接一次提交了。

最后,我們每次操作完數據庫之后都要手動關閉,可不可以寫成自動關閉的呢?

聯想到我們之前學過的文件操作,使用with語句可以實現縮進結束自動關閉文件句柄的例子。

我們來把我們的數據庫連接類SQLManager類再優化下,使其支持with語句操作。

class SQLManager(object):

    # 初始化實例方法
    def __init__(self):
        self.conn = None
        self.cursor = None
        self.connect()

    # 連接數據庫
    def connect(self):
        self.conn = pymysql.connect(
            host=DB_CONFIG["host"],
            port=DB_CONFIG["port"],
            user=DB_CONFIG["user"],
            passwd=DB_CONFIG["passwd"],
            db=DB_CONFIG["db"],
            charset=DB_CONFIG["charset"]
        )
        self.cursor = self.conn.cursor(cursor=pymysql.cursors.DictCursor)

    # 查詢多條數據
    def get_list(self, sql, args=None):
        self.cursor.execute(sql, args)
        result = self.cursor.fetchall()
        return result

    # 查詢單條數據
    def get_one(self, sql, args=None):
        self.cursor.execute(sql, args)
        result = self.cursor.fetchone()
        return result

    # 執行單條SQL語句
    def moddify(self, sql, args=None):
        self.cursor.execute(sql, args)
        self.conn.commit()

    # 執行多條SQL語句
    def multi_modify(self, sql, args=None):
        self.cursor.executemany(sql, args)
        self.conn.commit()

    # 創建單條記錄的語句
    def create(self, sql, args=None):
        self.cursor.execute(sql, args)
        self.conn.commit()
        last_id = self.cursor.lastrowid
        return last_id

    # 關閉數據庫cursor和連接
    def close(self):
        self.cursor.close()
        self.conn.close()

    # 進入with語句自動執行
    def __enter__(self):
        return self
    
    # 退出with語句塊自動執行
    def __exit__(self, exc_type, exc_val, exc_tb):
        self.close()

現階段,我們只需要優化到這一步就可以,后面的項目實戰中會繼續優化。如使用數據庫連接池等。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM