浅谈Python访问MySQL的正确姿势


Posted in Python onJanuary 07, 2020

Py2 时代,访问 MySQL 数据库的模块除了 PyMySQL 和 MySQL-python 之外,还有以速度见长的 Umysql,以及非常小众的 Oursql 模块。进入了 Py3 时代之后,PyMySQL 与时俱进,顺利升级到 Py3 版本, MySQL-python 则被它的一个 Py3 分支——mysqlclient 取代,而 Umysql 和 Oursql 则停留在了属于它们的那个时代。

下表给出了 PyMySQL 模块和 mysqlclient 模块在安装方式、导入方式、支持的Python版本和数据库版本等方面的比较。因为缺少可信的资料,这里没有对两个模块的性能做出比较。不过,PyMySQL 明确声明支持最新的 MySQL 和 MariaDB,而 mysqlclient 关于数据库版本支持的描述显得模棱两可、似是而非,所以很多人也许会把 PyMySQL 作为首选。但从我们的实际应用来看,mysqlclient 并没有受到过数据库版本的限制。我更愿意把版本支持的表述解读为两个开发团队风格不同所致。

PyMySQL mysqlclient
安装方式 pip install PyMySQL pip install mysqlclient
导入方式 import pymysql import MySQLdb
Python版本 2.7 and >= 3.4 2.7 and >= 3.4
数据库版本 MySQL >= 5.5 MariaDB >= 5.5 MySQL versions from 3.23 to 5.5; 5.0 or newer recommended. MariaDB should also work.

有趣的是,不管是 PyMySQL,还是 MySQL-python,或者后来取而代之的 mysqlclient,它们在用法上几乎完全一致:都是基于 Python database API version 2.0,这个标准也被称作 PEP-0249。这意味着,我们不用修改代码,就可以更换数据库客户端。下面的应用实例证明了这一点:除了模块名字不一样,其余代码完全一致。

姿势1:以元组形式返回查询记录

我们以 PyMySQL 模块为例,先来看看最常见的用法:以元组形式返回查询记录。如果把代码中的 pymysql 改为 MySQLdb,可以轻松切换成 mysqlclient 模块。

>>> import pymysql
>>> db = pymysql.connect(
  host = 'localhost',
  user = 'xufive',
  password = '********',
  db = 'demo',
  charset = 'utf8'
)
>>> cursor = db.cursor()
>>> cursor.execute('select * from member where id = %s', (100,))
1
>>> print(cursor.fetchall())
((100, '370103********0012', '*9EE8E3304D69C3E9260F19C224EA5852129BF030', '王茁洋', '男', datetime.date(****, **, **), '', '济南', '济南泉景小学', '186********', Decimal('1812.50')),)
>>> cursor.close()
>>> db.close()

姿势2:以字典形式返回查询记录

查询结果以元组形式返回,有很多不便,我们需要知道元组各元素对应的是表结构中的哪一个字段(列)。下面的代码,实现了以字典形式返回查询记录。同样的,如果把代码中的 MySQLdb 改为 pymysql,可以轻松切换成 PyMySQL 模块。

>>> import MySQLdb.cursors
>>> db = MySQLdb.connect(
  host = 'localhost',
  user = 'xufive',
  password = '********',
  db = 'demo', 
  charset = 'utf8',
  cursorclass = MySQLdb.cursors.DictCursor
)
>>> with db.cursor() as cursor:
  sql = 'select * from member where id = %s'
  cursor.execute(sql, (100,))
  print(cursor.fetchall())
 1
({'id': 100, 'idcard': '370103********0012', 'passwd': '*9EE8E3304D69C3E9260F19C224EA5852129BF030', 'name': '王茁洋', 'sex': '男', 'birthday': datetime.date(****, **, **), 'title': '', 'address': '济南', 'club': '济南泉景小学', 'phone': '186********', 'rating': Decimal('1812.50')},)

姿势3:事务回滚

事务是关系型数据库的重要特性,NoSQL数据库、分布式数据库通常会淡化、甚至放弃事务。所谓事务是将一组DML(insert、update、delete)语句组合在一起形成一个逻辑单元,这些操作要么全部执行成功提交(commit),如果不成功就要回退到事务开始之前的状态(rollback),以确保不会停留在错误的中间状态。下面的代码演示了 MySQL 典型的事务回滚应用。

>>> import pymysql
>>> db = pymysql.connect(
  host = 'localhost',
  user = 'xufive',
  password = '********',
  db = 'demo',
  charset = 'utf8'
)

def transaction(db):
  try:
    db.begin()
    # 此处加入出错之后需要回滚的DML(insert、update、delete)语句
    db.commit()
    return True
  except:
    db.rollback()
    return False

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
解决python3 urllib中urlopen报错的问题
Mar 25 Python
python3学习笔记之多进程分布式小例子
Feb 13 Python
使用Python写一个量化股票提醒系统
Aug 22 Python
python3爬虫获取html内容及各属性值的方法
Dec 17 Python
python 实现将txt文件多行合并为一行并将中间的空格去掉方法
Dec 20 Python
解决.ui文件生成的.py文件运行不出现界面的方法
Jun 19 Python
django页面跳转问题及注意事项
Jul 18 Python
用Python抢火车票的简单小程序实现解析
Aug 14 Python
Python配置文件处理的方法教程
Aug 29 Python
在Python中字符串、列表、元组、字典之间的相互转换
Nov 15 Python
python 实现矩阵填充0的例子
Nov 29 Python
python的netCDF4批量处理NC格式文件的操作方法
Mar 21 Python
pytorch自定义二值化网络层方式
Jan 07 #Python
Pytorch: 自定义网络层实例
Jan 07 #Python
Python StringIO如何在内存中读写str
Jan 07 #Python
Python内置数据类型list各方法的性能测试过程解析
Jan 07 #Python
python模拟实现斗地主发牌
Jan 07 #Python
python全局变量引用与修改过程解析
Jan 07 #Python
python__new__内置静态方法使用解析
Jan 07 #Python
You might like
基于Snoopy的PHP近似完美获取网站编码的代码
2011/10/23 PHP
nodejs实用示例 缩址还原
2010/12/28 NodeJs
字符串的replace方法应用浅析
2011/12/06 Javascript
深入理解JavaScript中的浮点数
2016/05/18 Javascript
javascript js 操作数组 增删改查的简单实现
2016/06/20 Javascript
JS中的进制转换以及作用
2016/06/26 Javascript
微信小程序开发的四十个技术窍门总结(推荐)
2017/01/23 Javascript
浅谈在koa2中实现页面渲染的全局数据
2017/10/09 Javascript
在vue中封装可复用的组件方法
2018/03/01 Javascript
Angular学习笔记之集成三方UI框架、控件的示例
2018/03/23 Javascript
原生JS进行前后端同构
2018/04/22 Javascript
详解Js里的for…in和for…of的用法
2019/03/28 Javascript
Vue 组件修改根实例的数据的方法
2019/04/02 Javascript
JavaScript 性能提升之路(推荐)
2019/04/10 Javascript
Nodejs 识别图片类型的方法
2019/08/15 NodeJs
layui 中select下拉change事件失效的解决方法
2019/09/20 Javascript
vue.js中ref及$refs的使用方法解析
2019/10/08 Javascript
[58:58]2018DOTA2亚洲邀请赛 4.4 淘汰赛 TNC vs VG 第二场
2018/04/05 DOTA
详解Python中heapq模块的用法
2016/06/28 Python
Python元组操作实例分析【创建、赋值、更新、删除等】
2017/07/24 Python
python基础练习之几个简单的游戏
2017/11/10 Python
python实现员工管理系统
2018/01/11 Python
Python编程flask使用页面模版的方法
2018/12/28 Python
python类的实例化问题解决
2019/08/31 Python
python实现统计代码行数的小工具
2019/09/19 Python
python正则过滤字母、中文、数字及特殊字符方法详解
2020/02/11 Python
Windows下实现将Pascal VOC转化为TFRecords
2020/02/17 Python
django日志默认打印request请求信息的方法示例
2020/05/17 Python
使用Python解析Chrome浏览器书签的示例
2020/11/13 Python
广州品高软件.net笔面试题目
2012/04/18 面试题
Prototype如何实现页面局部定时刷新
2013/08/06 面试题
高中毕业自我鉴定
2013/12/19 职场文书
物业保安员岗位职责制度
2014/01/30 职场文书
领导走群众路线整改措施思想汇报
2014/10/12 职场文书
荆州古城导游词
2015/02/06 职场文书
详解Python魔法方法之描述符类
2021/05/26 Python