浅谈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 变量类型及命名规则介绍
Jun 08 Python
在Python中操作时间之tzset()方法的使用教程
May 22 Python
使用Python中的tkinter模块作图的方法
Feb 07 Python
python Web开发你要理解的WSGI & uwsgi详解
Aug 01 Python
解决pyttsx3无法封装的问题
Dec 24 Python
Flask核心机制之上下文源码剖析
Dec 25 Python
python使用celery实现异步任务执行的例子
Aug 28 Python
pycharm显示远程图片的实现
Nov 04 Python
Python面向对象之多态原理与用法案例分析
Dec 30 Python
Python之Django自动实现html代码(下拉框,数据选择)
Mar 13 Python
Pythonic版二分查找实现过程原理解析
Aug 11 Python
Python Spyder 调出缩进对齐线的操作
Feb 26 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中路径问题的解决方案
2006/10/09 PHP
PHP 数据结构 算法 三元组 Triplet
2011/07/02 PHP
PHP自带方法验证邮箱、URL、IP是否合法的函数
2016/12/08 PHP
PHP实现的日历功能示例
2018/09/01 PHP
权威JavaScript 中的内存泄露模式
2007/08/13 Javascript
jquery实现树形二级菜单实例代码
2013/11/20 Javascript
为指定的元素添加遮罩层的示例代码
2014/01/15 Javascript
angularjs指令中的compile与link函数详解
2014/12/06 Javascript
jQuery中DOM树操作之复制元素的方法
2015/01/23 Javascript
javascript结合CSS实现苹果开关按钮特效
2015/04/07 Javascript
Javascript实现商品秒杀倒计时(时间与服务器时间同步)
2015/09/16 Javascript
jquery判断iPhone、Android设备类型
2016/09/14 Javascript
JS实现页面中所有img对象添加onclick事件及新窗口查看图片的方法
2016/12/27 Javascript
Javascript实现登录记住用户名和密码功能
2017/03/22 Javascript
浅谈angularjs依赖服务注入写法的注意点
2017/04/24 Javascript
Vue仿手机qq的实例代码(demo)
2017/09/08 Javascript
详解vue2 $watch要注意的问题
2017/09/08 Javascript
微信小程序倒计时功能实现代码
2017/11/09 Javascript
在Vue组件中获取全局的点击事件方法
2018/09/06 Javascript
nodejs二进制与Buffer的介绍与使用
2019/07/11 NodeJs
[46:55]LGD vs Liquid 2019国际邀请赛小组赛 BO2 第一场 8.16
2019/08/19 DOTA
python设置windows桌面壁纸的实现代码
2013/01/28 Python
Python无损音乐搜索引擎实现代码
2018/02/02 Python
用python求一个数组的和与平均值的实现方法
2019/06/29 Python
Python的Tkinter点击按钮触发事件的例子
2019/07/19 Python
使用 tf.nn.dynamic_rnn 展开时间维度方式
2020/01/21 Python
使用Python-OpenCV消除图像中孤立的小区域操作
2020/07/05 Python
Python3如何使用tabulate打印数据
2020/09/25 Python
PatPat香港:婴童服饰和亲子全家装在线购物
2020/09/27 全球购物
面试后感谢信
2014/02/01 职场文书
优秀团员事迹材料1000字
2014/08/20 职场文书
公共场所禁烟倡议书
2014/08/30 职场文书
小学三八妇女节活动总结
2015/02/06 职场文书
汶川大地震感悟
2015/08/10 职场文书
解决golang 关于全局变量的坑
2021/05/06 Golang
详解vue中v-for的key唯一性
2021/05/15 Vue.js