pymysql库以及DBUtils库的使用指南
Python操作数据库
本文主要介绍如何使用pymysql库以及DBUtils库来连接MySQL数据库。
一 准备
1 几个概念
2 几个概念间关系
二 安装模块
Python 程序想要操作数据库,首先需要安装 模块 来进行操作,下面使用pip命令安装PyMSQL模块
1 |
|
如果没有pip3命令那么需要确认环境变量是否有添加,安装完毕后测试是否安装完毕。
1 |
|
三 Pymysql 基本使用
连接数据库并执行sql语句的一般流程是:
- 建立连接
- 获取游标(创建)
- 执行SQL语句
- 提交事务
- 释放资源
对应到代码上的逻辑为:
- 导入相应的Python模块
- 使用connect函数连接数据库,并返回一个Connection对象
- 通过Connection对象的cursor方法,返回一个Cursor对象
- 通过Cursor对象的execute方法执行SQL语句
- 如果执行的是查询语句,通过Cursor对象的fetchall语句获取返回结果
- 调用Cursor对象的close关闭Cursor
- 调用Connection对象的close方法关闭数据库连接
connection 对象(生成对象的方法参数、对象方法)
cursor 对象(对象方法、fetch 方法)
3.1 实现
连接数据库
1 |
|
PS: 在实际的编程过程中,一般不会直接调用begin、commit和rollback函数,而是通过上下文管理器实现事务的提交与回滚操作
。
利用游标操作数据库
查询类SQL
1 |
|
非查询类SQL
1 |
|
PS: 使用pymysql来连接数据库时,单线程应用完全没有问题,但如果涉及到多线程应用那么就需要加锁,一旦加锁那么连接势必就会排队等待,当请求比较多时,性能就会降低了。因此,实际使用中,通常会使用数据库的连接池技术,来访问数据库达到资源复用的目的。
四 数据库连接池DBUtils
DBUtils 是一套用于管理数据库连接池的包,并允许对非线程安全的数据库接口进行线程安全包装。它能为高频度高并发的数据库访问提供更好的性能,可以自动管理连接对象的创建和释放。
连接池对性能的提升:
使用连接池可以进行长连接,直接从一个空闲的连接中获取,不需要重新初始化连接,提升获取连接的速度
关闭连接的时候,把连接放回连接池,而不是真正的关闭,所以可以减少频繁地打开和关闭连接
PS:如果不执行conn.close() 会导致线程不断创建连接,超过了连接池能容纳的最大连接数而报错: pymysql.err.OperationalError
,1040
, 'Too many connections'
DBUtils提供两种外部接口:
PersistentDB
: 提供线程专用的数据库连接,并自动管理连接。(为每一个线程创建一个)PooledDB
: 提供线程间可共享的数据库连接,并自动管理连接。(常用)
PooledDB
和 PersistentDB
都通过回收数据库连接,且即使数据库连接中断也能保持稳定性,从而达到提升数据库访问性能的目的。那么在现实场景中应该如何选择呢?
PooledDB 常用于多线程的情况。如果你的程序频繁地启动和关闭线程,最好使用这个;
PersistentDB 常用于单线程的情况。PersistentDB 会为每个线程创建一个,资源消耗太大。如果你的程序只是在单个线程上进行频繁的数据库连接,最好使这个;
4.1 安装
1 |
|
4.2 使用
连接池对象只初始化一次,一般可以作为模块级代码来确保。
PersistentDB
实现了稳定,线程仿射(thread-affine),持久化的数据库连接。某个线程第一次开启一个数据库连接时,该连接将用于此特定线程。即使在线程中关闭连接,连接也会保持打开状态,以便同一个线程的下一次连接请求直接使用。线程结束时该连接会自动关闭。图解地址
1 |
|
NOTE:需要在连接上调用begin()
方法明确开启事务。这可以确保a.只在事务完成时才重新打开连接b.连接被同一个线程重用时回滚。
PooledDB
DBUtils.PooledDB
实现了稳定、线程安全的缓存连接池。图解地址
相关配置参数说明:
PooledDB 参数 | 参数说明 |
---|---|
mincached | 初始化时,链接池中至少创建的空闲的链接,0表示不创建 |
maxcached | 连接池中允许的闲置的最多连接数量(缺省值 0和None不限制) |
maxshared | 允许的最大共享连接数(0或None表示所有连接都是专用的) |
maxconnections | 连接池允许的最大连接数,0和None表示不限制连接数 |
blocking | 连接池中如果没有可用连接后,是否阻塞等待。True:等待;False:抛出异常 |
maxusage | 单个连接的最大允许复用次数(缺省值 0 或 None 代表不限制的复用).当达到最大数时,连接会自动重新连接(关闭和重新打开) |
setsession | 开始会话前执行的命令列表 |
ping | 如果ping() 方法可用,该值表示何时使用ping()方法检查连接(`0 = None = never) |
closeable | 如果设置为True,将允许手动close()连接,默认为False,忽略关闭连接的操作,只在线程终止时自动关闭 |
1 |
|
NOTE: 对于不再使用的连接,调用close()方法回收到连接池。
NOTE: 需要在连接上调用begin()方法明确开启事务。这可以确保:a.只在事务完成时才重新打开连接;b.连接被同一个线程重用时回滚;c.连接不会被其他线程共享
4.3 遇到的问题
- 正常情况下,mysql的设置的timeout是8个小时(28800秒),也就是说,如果一个连接8个小时都没有操作,那么mysql会主动的断开连接,当这个连接再次尝试查询的时候就会报个”
2013, 'Lost connection to MySQL server during query'
错误”
1 |
|
- 很多使用DBUtils.PooledDB模块建立连接池,使用cursor()来建立多线程连接,在执行SQL查询的时候会报错:2014, “Commands out of sync; you can’t run this command now”
1 |
|
4.4 思维导图总结
模式一
参考
DBUtils-数据库连接池:https://www.jianshu.com/p/f94bc9ce0842
数据库连接池DBUtils使用 https://cloud.tencent.com/developer/article/1578187
Python DBUtils 连接池对象 (PooledDB) https://my.oschina.net/u/4357988/blog/3347902
《python DbUtils 使用教程》https://cloud.tencent.com/developer/article/1568031
《python数据库连接工具DBUtils》https://segmentfault.com/a/1190000017952033