浅谈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 相关文章推荐
python学习数据结构实例代码
May 11 Python
Python抓取百度查询结果的方法
Jul 08 Python
Python中模块与包有相同名字的处理方法
May 05 Python
python和opencv实现抠图
Jul 18 Python
通过python实现弹窗广告拦截过程详解
Jul 10 Python
PyCharm 2019.3发布增加了新功能一览
Dec 08 Python
Python内置函数locals和globals对比
Apr 28 Python
Python中格式化字符串的四种实现
May 26 Python
Python 程序报错崩溃后如何倒回到崩溃的位置(推荐)
Jun 23 Python
python如何停止递归
Sep 09 Python
Python 实现集合Set的示例
Dec 21 Python
如何基于python实现单目三维重建详解
Jun 25 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
用PHP实现将GB编码转换为UTF8
2006/11/25 PHP
php判断变量类型常用方法
2012/04/24 PHP
PHP CURL CURLOPT参数说明(curl_setopt)
2013/09/30 PHP
PHP设置一边执行一边输出结果的代码
2013/09/30 PHP
jQuery动画效果animate和scrollTop结合使用实例
2014/04/02 Javascript
JavaScript实现按照指定长度为数字前面补零输出的方法
2015/03/19 Javascript
原生JavaScript实现异步多文件上传
2015/12/02 Javascript
JS中作用域和变量提升(hoisting)的深入理解
2016/10/31 Javascript
从零开始封装自己的自定义Vue组件
2018/10/09 Javascript
基于vue开发微信小程序mpvue-docs跳转页面功能
2019/04/10 Javascript
在Vue中用canvas实现二维码和图片合成海报的方法
2019/06/10 Javascript
如何对react hooks进行单元测试的方法
2019/08/14 Javascript
JS实现提示框跟随鼠标移动
2019/08/27 Javascript
[02:52]DOTA2新手基础教程 米波
2014/01/21 DOTA
[02:04]2016国际邀请赛中国区预选赛VG.R晋级之路
2016/07/01 DOTA
[41:52]DOTA2-DPC中国联赛 正赛 CDEC vs Dynasty BO3 第二场 2月22日
2021/03/11 DOTA
python简单判断序列是否为空的方法
2015/06/30 Python
Python干货:分享Python绘制六种可视化图表
2018/08/27 Python
python实现图像检索的三种(直方图/OpenCV/哈希法)
2019/08/08 Python
Python API自动化框架总结
2019/11/12 Python
Pytorch.nn.conv2d 过程验证方式(单,多通道卷积过程)
2020/01/03 Python
Python基于smtplib模块发送邮件代码实例
2020/05/29 Python
opencv+python实现鼠标点击图像,输出该点的RGB和HSV值
2020/06/02 Python
Python执行时间的几种计算方法
2020/07/31 Python
法国二手手袋、手表和奢侈珠宝购物网站:Collector Square
2018/07/05 全球购物
写给女朋友的道歉信
2014/01/12 职场文书
事业单位公务员的职业生涯规划
2014/01/15 职场文书
应届毕业生应聘自荐信范文
2014/02/26 职场文书
聘任书模板
2014/03/29 职场文书
推普周国旗下讲话稿
2014/09/21 职场文书
2015年八一建军节活动总结
2015/03/20 职场文书
2015小学教师年度工作总结
2015/05/12 职场文书
2015年宣传部个人工作总结
2015/05/14 职场文书
2016年党员岗位承诺书
2016/03/24 职场文书
使用Python+OpenCV进行卡类型及16位卡号数字的OCR功能
2021/08/30 Python
Python 一键获取电脑浏览器的账号密码
2022/05/11 Python