浅谈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 17 Python
python连接字符串的方法小结
Jul 13 Python
Python的Flask框架中使用Flask-SQLAlchemy管理数据库的教程
Jun 14 Python
利用Python生成文件md5校验值函数的方法
Jan 10 Python
Tensorflow实现AlexNet卷积神经网络及运算时间评测
May 24 Python
PyQt5 QTableView设置某一列不可编辑的方法
Jun 25 Python
对Django url的几种使用方式详解
Aug 06 Python
python 读取更新中的log 或其它文本方式
Dec 24 Python
Python 实现国产SM3加密算法的示例代码
Sep 21 Python
基于django和dropzone.js实现上传文件
Nov 24 Python
python excel和yaml文件的读取封装
Jan 12 Python
利用Selenium添加cookie实现自动登录的示例代码(fofa)
May 08 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 变量的定义方法
2010/01/26 PHP
php shell超强免杀、减少体积工具实现代码
2012/10/16 PHP
php使用ftp远程上传文件类(完美解决主从文件同步问题的方法)
2016/09/23 PHP
php用户密码加密算法分析【Discuz加密算法】
2016/10/12 PHP
php-app开发接口加密详解
2018/04/18 PHP
PHP钩子实现方法解析
2019/05/21 PHP
javascript:history.go()和History.back()的区别及应用
2012/11/25 Javascript
jquery插件autocomplete用法示例
2016/07/01 Javascript
jQuery和CSS仿京东仿淘宝列表导航菜单
2017/01/04 Javascript
jQuery实现遍历复选框的方法示例
2017/03/06 Javascript
详解微信开发中snsapi_base和snsapi_userinfo及静默授权的实现
2017/03/11 Javascript
jQuery使用eraser.js插件实现擦除、刮刮卡效果的方法【附eraser.js下载】
2017/04/28 jQuery
Vue.js实现列表清单的操作方法
2017/11/15 Javascript
Vue shopCart 组件开发详解
2018/01/26 Javascript
Node.JS段点续传:Nginx配置文件分段下载功能的实现方法
2018/03/12 Javascript
如何基于vue-cli3.0构建功能完善的移动端架子
2019/04/24 Javascript
Python UnicodeEncodeError: 'gbk' codec can't encode character 解决方法
2015/04/24 Python
Python实现的双色球生成功能示例
2017/12/18 Python
Python使用re模块实现信息筛选的方法
2018/04/29 Python
基于python实现高速视频传输程序
2019/05/05 Python
python3实现二叉树的遍历与递归算法解析(小结)
2019/07/03 Python
python查找重复图片并删除(图片去重)
2019/07/16 Python
一行Python代码制作动态二维码的实现
2019/09/09 Python
windows下python安装pip方法详解
2020/02/10 Python
完美解决pyinstaller打包报错找不到依赖pypiwin32或pywin32-ctypes的错误
2020/04/01 Python
python 两种方法修改文件的创建时间、修改时间、访问时间
2020/09/26 Python
scrapy头部修改的方法详解
2020/12/06 Python
英国领先的杂志订阅网站:Magazine.co.uk
2018/01/25 全球购物
Tirendo比利时:在线购买轮胎
2018/10/22 全球购物
技校生自我鉴定
2013/12/08 职场文书
个人充满哲理的自我评价
2014/02/20 职场文书
道德大讲堂实施方案
2014/05/14 职场文书
2015年家长学校工作总结
2015/04/22 职场文书
MYSQL数据库使用UTF-8中文编码乱码的解决办法
2021/05/26 MySQL
Navicat for MySQL的使用教程详解
2021/05/27 MySQL
nginx作grpc的反向代理踩坑总结
2021/07/07 Servers