浅谈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爬取读者并制作成PDF
Mar 10 Python
python输出当前目录下index.html文件路径的方法
Apr 28 Python
Python计算已经过去多少个周末的方法
Jul 25 Python
利用Python中unittest实现简单的单元测试实例详解
Jan 09 Python
Python实现12306火车票抢票系统
Jul 04 Python
pygame实现五子棋游戏
Oct 29 Python
Django ValuesQuerySet转json方式
Mar 16 Python
Python3.7 读取音频根据文件名生成脚本的代码
Apr 07 Python
你应该知道的Python3.6、3.7、3.8新特性小结
May 12 Python
Django中的模型类设计及展示示例详解
May 29 Python
Python学习之路之pycharm的第一个项目搭建过程
Jun 18 Python
Python JSON常用编解码方法代码实例
Sep 05 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
PHP7使用ODBC连接SQL Server2008 R2数据库示例【基于thinkPHP5.1框架】
2019/05/06 PHP
php-fpm超时时间设置request_terminate_timeout资源问题分析
2019/09/27 PHP
js获取变量
2006/08/24 Javascript
javascript 写的一个简单的timer
2009/07/30 Javascript
jQuery学习总结之jQuery事件
2014/06/30 Javascript
在IE8上JS实现combobox支持拼音检索功能
2016/05/23 Javascript
Ionic + Angular.js实现图片轮播的方法示例
2017/05/21 Javascript
详解angularjs 关于ui-router分层使用
2017/06/12 Javascript
不得不看之JavaScript构造函数及new运算符
2017/08/21 Javascript
angularjs实现猜大小功能
2017/10/23 Javascript
JS点击动态添加标签、删除指定标签的代码
2018/04/18 Javascript
JavaScript闭包相关知识解析
2019/10/19 Javascript
file-loader打包图片文件时路径错误输出为[object-module]的解决方法
2020/01/03 Javascript
[01:19:35]DOTA2上海特级锦标赛主赛事日 - 3 败者组第三轮#2Fnatic VS OG第二局
2016/03/05 DOTA
py2exe 编译ico图标的代码
2013/03/08 Python
python实现在sqlite动态创建表的方法
2015/05/08 Python
Python读取word文本操作详解
2018/01/22 Python
python查询mysql,返回json的实例
2018/03/26 Python
python pygame模块编写飞机大战
2018/11/20 Python
Python底层封装实现方法详解
2020/01/22 Python
TensorFlow内存管理bfc算法实例
2020/02/03 Python
Python基于smtplib协议实现发送邮件
2020/06/03 Python
Django后端分离 使用element-ui文件上传方式
2020/07/12 Python
Python常用数据分析模块原理解析
2020/07/20 Python
如何开发一款堪比APP的微信小程序(腾讯内部团队分享)
2016/12/22 HTML / CSS
html特殊符号示例 html特殊字符编码对照表
2014/01/14 HTML / CSS
法国和欧洲海边和滑雪度假:Pierre & Vacances
2017/01/04 全球购物
新西兰最大的天然保健及护肤品网站:HealthPost(直邮中国)
2021/02/13 全球购物
初一科学教学反思
2014/01/27 职场文书
中等生评语大全
2014/05/04 职场文书
关心下一代工作先进事迹
2014/08/15 职场文书
校园运动会广播稿
2014/10/06 职场文书
高中生思想道德自我评价
2015/03/09 职场文书
幼儿园托班开学寄语(2015秋季)
2015/05/27 职场文书
市场营销计划书
2019/04/24 职场文书
创业计划之特色精品店
2019/08/12 职场文书