浅谈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的设计模式编程入门指南
Apr 02 Python
Python中functools模块的常用函数解析
Jun 30 Python
详解Python map函数及Python map()函数的用法
Nov 16 Python
python实现闹钟定时播放音乐功能
Jan 25 Python
python复制文件到指定目录的实例
Apr 27 Python
python 实现让字典的value 成为列表
Dec 16 Python
python pprint模块中print()和pprint()两者的区别
Feb 10 Python
python编写一个会算账的脚本的示例代码
Jun 02 Python
python 如何快速复制序列
Sep 07 Python
Pycharm常用快捷键总结及配置方法
Nov 14 Python
pycharm最新激活码有效期至2100年(亲测可用)
Feb 05 Python
让文件路径提取变得更简单的Python Path库
May 27 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编写和读取XML的几种方式
2013/01/12 PHP
sae使用smarty模板的方法
2013/12/17 PHP
淘宝ip地址查询类分享(利用淘宝ip库)
2014/01/07 PHP
PHP连接sql server 2005环境配置及问题解决
2014/08/08 PHP
php cookie工作原理与实例详解
2016/07/18 PHP
PHP中命名空间的使用例子
2019/03/22 PHP
写入cookie的JavaScript代码库 cookieLibrary.js
2009/10/24 Javascript
理解Javascript闭包
2013/11/01 Javascript
jquery实现侧边弹出的垂直导航
2014/12/09 Javascript
JavaScript实现select添加option
2015/07/03 Javascript
利用javascript实现的三种图片放大镜效果实例(附源码)
2017/01/23 Javascript
js仿淘宝评价评分功能
2017/02/28 Javascript
微信小程序开发之toast提示插件使用示例
2017/06/08 Javascript
javaScript中封装的各种写法示例(推荐)
2017/07/03 Javascript
使用AngularJS编写多选按钮选中时触发指定方法的指令代码详解
2017/07/24 Javascript
详解VueJS 数据驱动和依赖追踪分析
2017/07/26 Javascript
jQuery中库的引用方法
2018/01/06 jQuery
Vue2.X 通过AJAX动态更新数据
2018/07/17 Javascript
原生JS实现手动轮播图效果实例代码
2018/11/22 Javascript
如何在JavaScript中优雅的提取循环内数据详解
2019/03/04 Javascript
node基于async/await对mysql进行封装
2019/06/20 Javascript
微信小程序实现通讯录列表展开收起
2020/11/18 Javascript
Python实现时钟显示效果思路详解
2018/04/11 Python
python读取图片并修改格式与大小的方法
2018/07/24 Python
解决python中遇到字典里key值为None的情况,取不出来的问题
2018/10/17 Python
Python使用Turtle库绘制一棵西兰花
2019/11/23 Python
Python自动化测试基础必备知识点总结
2021/02/07 Python
CSS3的Flexbox布局的简明入门指南
2016/04/08 HTML / CSS
HTML5拖拽文件上传的示例代码
2021/03/04 HTML / CSS
C#面试问题
2016/07/29 面试题
如何查看在weblogic中已经发布的EJB
2012/06/01 面试题
2015年元旦晚会活动总结(学生会)
2014/11/28 职场文书
2014年污水处理厂工作总结
2014/12/19 职场文书
Nginx搭建rtmp直播服务器实现代码
2021/03/31 Servers
python 爬取华为应用市场评论
2021/05/29 Python
golang中的struct操作
2021/11/11 Golang