转载自: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()

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

Python学习(二十九)—— pymysql操作数据库优化的更多相关文章

  1. python学习 (二十九) range函数

    1:list函数可以将其他类型转成list. print(list(range(0, 10))) 2: list函数把元组转成list t = (1, 3, 3, 5) print(list(t)) ...

  2. 前端学习(二十九)nodejs(笔记)

    后台语言    java     php     .Net     python    Node.js------------------------------------------------- ...

  3. Java从零开始学二十九(大数操作(BigIntger、BigDecimal)

    一.BigInteger 如果在操作的时候一个整型数据已经超过了整数的最大类型长度long的话,则此数据就无法装入,所以,此时要使用BigInteger类进行操作. 不可变的任意精度的整数.所有操作中 ...

  4. python学习二,字符串常用操作

    字符串可以说是在日常开发中应用最广泛的了,现在来总结下有关python中有关字符串一些常用操作 首先我们声明一个字符串变量 str = "hello world" 下面我们来依次介 ...

  5. ballerina 学习二十九 数据库操作

    ballerina 数据操作也是比较方便的,官方也我们提供了数据操作的抽象,但是我们还是依赖数据库驱动的. 数据库驱动还是jdbc模式的 项目准备 项目结构 ├── mysql_demo │ ├── ...

  6. Python学习二十八周(vue.js)

    一.指令 1.一个例子简单实用vue: 下载vue.js(这里实用1.0.21版本) 编写html代码: <!DOCTYPE html> <html lang="en&qu ...

  7. python 学习笔记十九 django深入学习四 cookie,session

    缓存 一个动态网站的基本权衡点就是,它是动态的. 每次用户请求一个页面,Web服务器将进行所有涵盖数据库查询到模版渲染到业务逻辑的请求,用来创建浏览者需要的页面.当程序访问量大时,耗时必然会更加明显, ...

  8. python学习笔记(十)、文件操作

    在前面我们了解到了没得模块,其中有一个模块为fileinput,为文件操作模块,不知道小伙伴们是否还记得? 1 打开文件 要打开文件,可以使用fileinput中的fileinput.input函数进 ...

  9. Python学习(十九) —— 前端基础之HTML

    转载自:http://www.cnblogs.com/liwenzhou/p/7988087.html 一.HTML介绍 1.Web服务本质 import socket sk = socket.soc ...

随机推荐

  1. <转载>ford-fulkerson算法2

    原文链接https://www.cnblogs.com/luweiseu/archive/2012/07/14/2591573.html 作者:wlu 7. 网络流算法--Ford-Fulkerson ...

  2. [Linux]流媒体服务器概述

    二.何为流媒体与流式传输? 2.1 流媒体 「流媒体」是指采用「流式传输」的方式在Internet播放的媒体格式,流媒体最大的特点就是「边下边播」,常用的流媒体格式有FLV(使用FLASH作为视频播放 ...

  3. 进程命令ps/top/kill

    进程: 通俗的说就是 当前正在执行的一个程序 命令: ps 英文: process status 作用: 查看进程的详细状况 选项: a:显示终端上的所有进程,包括其他用户的进程 u:显示进程的详细状 ...

  4. cocos2d内存管理,类的生命周期

    下面资料来自<Cocos2d-x之Lua核心编程>

  5. 调整linux进程优先级

    使用环境 当服务器资源比较紧张的时候,可以通过调整优先级来优先处理某个进程的请求 查看进行优先级(top) 优先级由 -20~19这个范围来表示优先级大小,数值越小,优先级越高, 设置方法: 使用re ...

  6. python-常用模块xml、shelve、configparser、hashlib

    一.shelve模块 shelve模块也是用来序列化的. 使用方法: 1.open 2.读写 3.close import shelve # 序列化 sl = shelve.open('shlvete ...

  7. kindeditor用法简单介绍(转)

    1,首先去官网下载http://www.kindsoft.net/ 2,解压之后如图所示: 由于本人做的是用的是JSP,所以ASP,PHP什么的就用不上了,直接把那些去掉然后将整个文件夹扔进Myecl ...

  8. headless&unittest

    为什么要使用 headless 测试? headless broswer 可以给测试带来显著好处: 对于 UI 自动化测试,少了真实浏览器加载 css,js 以及渲染页面的工作.无头测试要比真实浏览器 ...

  9. linux命令知识点

    1. 例二:列出当前目录中所有以“t”开头的目录的详细内容,可以使用如下命令: 命令:ls -l t* 例六:计算当前目录下的文件数和目录数 命令: ls -l * |grep "^-&qu ...

  10. SpringBoot图片上传(二)

    需求简介:做新增的时候,需要上传图片.(⊙o⊙)…这需求描述也太简单了吧,限制文件大小60*60 512kb ,第一次做,记录一下嗷,废话就不啰嗦了 上代码 代码: //html代码<div c ...