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()
现阶段,我们只需要优化到这一步就可以,后面的项目实战中会继续优化。如使用数据库连接池等。