浅谈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自动化部署工具Fabric的简单上手指南
Apr 19 Python
Python整型运算之布尔型、标准整型、长整型操作示例
Jul 21 Python
python中redis查看剩余过期时间及用正则通配符批量删除key的方法
Jul 30 Python
Python设计模式之组合模式原理与用法实例分析
Jan 11 Python
Python读取Pickle文件信息并计算与当前时间间隔的方法分析
Jan 30 Python
python 利用文件锁单例执行脚本的方法
Feb 19 Python
使用python list 查找所有匹配元素的位置实例
Jun 11 Python
pycharm下pyqt4安装及环境配置的教程
Apr 24 Python
解决keras,val_categorical_accuracy:,0.0000e+00问题
Jul 02 Python
python进行OpenCV实战之画图(直线、矩形、圆形)
Aug 27 Python
python 基于wx实现音乐播放
Nov 24 Python
Python torch.flatten()函数案例详解
Aug 30 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
文件上传类
2006/10/09 PHP
在PHP中使用灵巧的体系结构
2006/10/09 PHP
修改php.ini实现Mysql导入数据库文件最大限制的修改方法
2007/12/11 PHP
基于php常用正则表达式的整理汇总
2013/06/08 PHP
ThinkPHP实现生成和校验验证码功能
2017/04/28 PHP
PHP封装类似thinkphp连贯操作数据库Db类与简单应用示例
2019/05/08 PHP
模仿JQuery.extend函数扩展自己对象的js代码
2009/12/09 Javascript
jQuery LigerUI 使用教程入门篇
2012/01/18 Javascript
Javascript引用指针使用介绍
2012/11/07 Javascript
详解JS函数重载
2014/12/04 Javascript
js实现千分符和保留几位小数的简单实例
2016/08/01 Javascript
AngularJS表格详解及示例代码
2016/08/17 Javascript
JS简单实现tab切换效果的多窗口显示功能
2016/09/07 Javascript
jquery ajax后台返回list,前台用jquery遍历list的实现
2016/10/30 Javascript
js操作浏览器的参数方法
2017/01/21 Javascript
JavaScript评论点赞功能的实现方法
2017/03/13 Javascript
详解VUE的状态控制与延时加载刷新
2017/03/27 Javascript
vue中实现先请求数据再渲染dom分享
2018/03/17 Javascript
Webpack中publicPath路径问题详解
2018/05/03 Javascript
vue 下列表侧滑操作实例代码详解
2018/07/24 Javascript
JavaScript this绑定过程深入详解
2018/12/07 Javascript
ES6基础之展开语法(Spread syntax)
2019/02/21 Javascript
WEEX环境搭建与入门详解
2019/10/16 Javascript
微信小程序实现签字功能
2019/12/23 Javascript
在Python中使用全局日志时需要注意的问题
2015/05/06 Python
一波神奇的Python语句、函数与方法的使用技巧总结
2015/12/08 Python
python 列表输出重复值以及对应的角标方法
2019/06/11 Python
Python定时任务工具之APScheduler使用方式
2019/07/24 Python
Django 自定义分页器的实现代码
2019/11/24 Python
Pytorch: 自定义网络层实例
2020/01/07 Python
提升Nginx性能的一些建议
2021/03/31 Servers
前端JavaScript大管家 package.json
2021/11/02 Javascript
基于MySql验证的vsftpd虚拟用户
2021/11/07 MySQL
Html5获取用户当前位置的几种方式
2022/01/18 HTML / CSS
2021年国漫热度排行前十,完美世界上榜,第四是美国动画作品
2022/03/18 国漫
一文搞懂PHP中的抽象类和接口
2022/05/25 PHP