浅谈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的Urllib库的基本使用教程
Apr 30 Python
Python时间的精准正则匹配方法分析
Aug 17 Python
Python numpy实现数组合并实例(vstack,hstack)
Jan 09 Python
Python设计模式之命令模式简单示例
Jan 10 Python
Python subprocess模块详细解读
Jan 29 Python
如何优雅地改进Django中的模板碎片缓存详解
Jul 04 Python
解决pycharm运行程序出现卡住scanning files to index索引的问题
Jun 27 Python
Django使用模板后无法找到静态资源文件问题解决
Jul 19 Python
画pytorch模型图,以及参数计算的方法
Aug 17 Python
Python参数传递实现过程及原理详解
May 14 Python
Python2.x与3​​.x版本有哪些区别
Jul 09 Python
Python实现我的世界小游戏源代码
Mar 02 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正则的Unknown Modifier错误解决方法
2010/03/02 PHP
浅谈php中fopen不能创建中文文件名文件的问题
2017/02/06 PHP
详解配置 Apache 服务器支持 PHP 文件的解析
2017/02/15 PHP
PHP Socket网络操作类定义与用法示例
2017/08/30 PHP
神奇的7个jQuery 3D插件整理
2011/01/06 Javascript
JavaScript使用setTimeout实现延迟弹出警告框的方法
2015/04/07 Javascript
简介AngularJS中使用factory和service的方法
2015/06/17 Javascript
jQuery拖动布局其结果保存到数据库
2015/10/09 Javascript
解决js页面滚动效果scrollTop在FireFox与Chrome浏览器间的兼容问题的方法
2015/12/03 Javascript
ajax实现动态下拉框示例
2017/01/10 Javascript
代码详解JS操作剪贴板
2018/02/11 Javascript
Vue数据双向绑定原理及简单实现方法
2018/05/18 Javascript
node.js部署之启动后台运行forever的方法
2018/05/23 Javascript
使用canvas实现一个vue弹幕组件功能
2018/11/30 Javascript
layui form.render('select', 'test2') 更新渲染的方法
2019/09/27 Javascript
[06:44]2014DOTA2国际邀请赛-钥匙体育馆开战 开幕式振奋人心
2014/07/19 DOTA
Python使用MONGODB入门实例
2015/05/11 Python
Python中的super()方法使用简介
2015/08/14 Python
Python使用Srapy框架爬虫模拟登陆并抓取知乎内容
2016/07/02 Python
python 把数据 json格式输出的实例代码
2016/10/31 Python
利用python程序帮大家清理windows垃圾
2017/01/15 Python
利用python编写一个图片主色转换的脚本
2017/12/07 Python
TensorFlow查看输入节点和输出节点名称方式
2020/01/04 Python
Python 实现日志同时输出到屏幕和文件
2020/02/19 Python
MANGO官方网站:西班牙芒果服装品牌
2017/01/15 全球购物
如何利用XMLHTTP检测URL及探测服务器信息
2013/11/10 面试题
消防战士优秀事迹材料
2014/02/13 职场文书
学校运动会广播稿
2014/10/11 职场文书
成本会计岗位职责
2015/02/03 职场文书
2016年3月份红领巾广播稿
2015/12/21 职场文书
2016年情人节广告语
2016/01/28 职场文书
Ajax是什么?Ajax高级用法之Axios技术
2021/04/21 Javascript
详解Django的MVT设计模式
2021/04/29 Python
JS如何使用剪贴板操作Clipboard API
2021/05/17 Javascript
使用@Value值注入及配置文件组件扫描
2021/07/09 Java/Android
Python 一键获取电脑浏览器的账号密码
2022/05/11 Python