首页 > 数据库 >数据库连接池 - Pymysql

数据库连接池 - Pymysql

时间:2023-04-29 12:04:59浏览次数:28  
标签:cursor 数据库 Pymysql ------- sleep pymysql conn import 连接池

数据库连接池 + pymysql

最近想用小程序来做个移动BI, 然后涉及后端接口部分打算用 Python 的 flask 框架整一波, 主要听闻它比较轻量, 简单和可灵活配置, 这就和我很对味. 毕竟我主要搞数据用的就是 sql 而已, 只要有个服务器提供接口就行. 真正开始来写接口的时候, 就遇到这个数据库的问题, 关于查询效率, 和优雅.

我在工作中偶尔有一些数据处理或者逻辑分析的场景下, 即不通过BI平台, 大量用 pandas + sql 来操作. 我们数据的 ADS 层几乎都在 mysql 故用这个 pymysql 作为驱动连接工具是很好用的.

低频分析查询-随便搞

针对低频查询数据, 通常写法是这样的:

import pymysql

# 1.创建连接
conn = pymysql.connect(
    host='127.0.0.1',
    port=3306,
    user='root',
    passwd='123456',
    db='cj'
)

# 3.创建游标
cursor = conn.cursor()

# 4. 执行sql语句和获取数据, 以经典的超市数据为例
cursor.execute('select order_id, province from market limit 2;')
data = cursor.fetchall()
print(data)

# 5. 关闭连接(同时也就关闭了cursor, 不关可能造成锁表)
conn.close()
(('US-2023-1357144', '浙江'), ('CN-2023-1973789', '四川'))

高频分析查询-连接池

但如果变成了web, 每次访问接口都要查询数据, 如果每次都要重新进行 connect 那这个就有点低效了.

若在外层只连接一次, 重复用 cursor 的话又可能会造成锁表和线程异常问题.

因此, 创建一个数据库连接池来进行任务管理是非常必要的. 即可通过一个 pool 来自动创建多个连接和资源回收, 这样就又高效又优雅.

在 pyhton 中, 我们用 dbutils 用作池管理, 驱动还是用 pymysql, 写法如下:

import pymysql 
from pymysql import cursors
from dbutils.pooled_db import PooledDB


pool = PooledDB(
    creator=pymysql,
    # 创建最大连接
    maxconnections=6,
    mincached=2,
    maxcached=3,
    maxshared=4,
    blocking=True,
    maxusage=None,
    setsession=[],
    ping=0,
    # 这一坨会传给上面的 pymysql
    host='127.0.0.1',
    port=3306,
    user='root',
    passwd='123456',
    database='cj',
    charset='utf8',
    # 让查询结果是一个 dict
    cursorclass=cursors.DictCursor
)


# 使用上和 mysql 是一样的
conn = pool.connection()
cursor = conn.cursor()

cursor.execute('select order_id, province from market limit 2;')
data = cursor.fetchall()
print(data)

# 这里并没有关闭连接, 而是放进了连接池 pool 
conn.close()

结果也是一样的.

(('US-2023-1357144', '浙江'), ('CN-2023-1973789', '四川'))

模拟多用户请求

上面的作用不太直观, 这里用多线程 threading 来模拟多请求的情况. 假设每次最大连接 3次, 至少1次的配置,

通过 sleep 减速一下则可以看到每次 3个连接这样, 一波波处理:

import pymysql 
from pymysql import cursors
from dbutils.pooled_db import PooledDB


pool = PooledDB(
    creator=pymysql,
    # 创建最大连接, 这里假设搞个3
    maxconnections=3,
    mincached=1,
    maxcached=3,
    maxshared=4,
    blocking=True,
    maxusage=None,
    setsession=[],
    ping=0,
    # 这一坨会传给上面的 pymysql
    host='127.0.0.1',
    port=3306,
    user='root',
    passwd='123456',
    database='cj',
    charset='utf8',
    # 让查询结果是一个 dict
    cursorclass=cursors.DictCursor
)


# 模拟多个请求的情况


from threading import Thread

def task(num):
    conn = pool.connection()
    cursor = conn.cursor()

    cursor.execute('select sleep(3);')
    data = cursor.fetchall()

    print(num, '-------', data)
    conn.close()

# 多线程任务测试
for i in range(20):
    t = Thread(target=task, args=(i,))
    # 启动
    t.start()

一波波的输出如下:

2 ------- [{'sleep(3)': 0}]
1 ------- [{'sleep(3)': 0}]
3 ------- [{'sleep(3)': 0}]

0 ------- [{'sleep(3)': 0}]
4 ------- [{'sleep(3)': 0}]
5 ------- [{'sleep(3)': 0}]

7 ------- [{'sleep(3)': 0}]
6 ------- [{'sleep(3)': 0}]
10 ------- [{'sleep(3)': 0}]

8 ------- [{'sleep(3)': 0}] 
11 ------- [{'sleep(3)': 0}]
9 ------- [{'sleep(3)': 0}] 

14 ------- [{'sleep(3)': 0}]
12 ------- [{'sleep(3)': 0}]
15 ------- [{'sleep(3)': 0}]

13 ------- [{'sleep(3)': 0}]
16 ------- [{'sleep(3)': 0}]
18 ------- [{'sleep(3)': 0}]

17 ------- [{'sleep(3)': 0}]
19 ------- [{'sleep(3)': 0}]

可以看到连接池简直太优秀了, 非常实用和优雅呀.

耐心和恒心, 总会获得回报的.



标签:cursor,数据库,Pymysql,-------,sleep,pymysql,conn,import,连接池
From: https://blog.51cto.com/u_14195239/6236694

相关文章

  • 数据库的基本操作
    结构化查询语句分类创建数据表数据类型字符串类型日期和时间型数值类型NULL值设置数据表的类型数据表的存储位置设置数据表字符集修改表(ALTERTABLE)删除数据表其他结构化查询语句分类数据库操作创建数据库:createdatabase[ifnotexists]数据库名;删除数据库......
  • 数据库函数
    常用函数数据函数字符串函数日期和时间函数系统函数题目介绍实现数据加密常用函数1.数据函数SELECTABS(-8);/*绝对值*/SELECTCEILING(9.4);/*向上取整*/SELECTFLOOR(9.4);/*向下取整*/SELECTRAND();/*随机数,返回一个0-1之间的随机数*/SELECT......
  • NFO20003 数据库
    DatabaseSystemsINFO20003A2S12023Page1of7INFO20003Semester1,2023Assignment2:SQLDue:6:00pmFriday,28April2023Weighting:10%ofyourtotalassessmentResearchPapersDatabaseDescriptionYouandagroupoffellowundergradshavecreatedast......
  • [数据库]MYSQL之授予/查验binlog权限
    在后端做主从备份;亦或是在大数据领域中,各类CDC同步(Canal/FlinkCDC等),均会基于MYSQL的binlog来实现。因此,知道需要哪些权限?怎么查验去、怎么授权就很重要了。感觉网上的文章没成体系地清楚,而今天工作上处理问题的过程中遇到了此疑问,且曾多次对此产生疑问,自然便有了这一篇,作......
  • 开心档之MySQL 创建数据库
    MySQL数据类型MySQL中定义数据字段的类型对你数据库的优化是非常重要的。MySQL支持多种类型,大致可以分为三类:数值、日期/时间和字符串(字符)类型。数值类型MySQL支持所有标准SQL数值数据类型。这些类型包括严格数值数据类型(INTEGER、SMALLINT、DECIMAL和NUMERIC),以及近似......
  • 开心档之MySQL 创建数据库
    MySQL创建数据库我们可以在登陆MySQL服务后,使用create命令创建数据库,语法如下:CREATEDATABASE数据库名;以下命令简单的演示了创建数据库的过程,数据名为RUNOOB:[root@host]#mysql-uroot-pEnterpassword:******#登录后进入终端mysql>createDATABASE......
  • Mysql数据库设计和事务
    一对一在任意一方建立外键,关联另一方主键一对多在多的一方建立外键关联另一方的主键多对多1.建立中间表2.中间表至少包含2个外键,分别关联双方主键内连接1.隐式连接select*fromemp,deptwhereemp.dep_id=dept.did   2.显式连接select*fromemp(inner)joindep......
  • python之cx_Oracle实现本地exe连接oracle数据库执行命令
    代码实现#-*-coding:GBK-*-importosimportcx_Oracle#导入cx_Oracle模块importtimedefgetData():conn=cx_Oracle.connect('username/password@ip:port/orcl')cur=conn.cursor()sql="SELECT*fromUSERwhereUSER_ID=\'......
  • oracle 数据库事务,提交,回滚,保存点,表的锁定,隐式锁,显示锁,写锁,读锁,排他锁,共享
    [color=red]数据库事务的概念[/color]事务是由相关操作构成的一个完整的操作单元。两次连续成功的COMMIT或ROLLBACK之间的操作,称为一个事务。在一个事务内,数据的修改一起提交或撤销,如果发生故障或系统错误,整个事务也会自动撤销。比如,我们去银行转账,操作......
  • double转为整型intValue()及sha1在线文件获取,文件都有一个唯一的sha1;jQuery事件方法;
    double转为整型intValue()及sha1在线文件获取,文件都有一个唯一的sha1Doubleindust=RankConstant.INIT_RADIO;indust.intValue()double由100.0---->100整型1.intValue()是java.lang.Number类的方法,Number是一个抽象类。Java中所有的数值类都继承它。也就是说,不单是Integer有int......