最近想用小程序来做个移动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}]

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

数据库连接池 - Pymysql的更多相关文章

  1. Python数据库连接池DBUtils(基于pymysql模块连接数据库)

    安装 pip3 install DBUtils DBUtils是Python的一个用于实现数据库连接池的模块. 此连接池有两种连接模式: # BDUtils数据库链接池: 模式一:基于threaing ...

  2. 3、flask之基于DBUtils实现数据库连接池、本地线程、上下文

    本篇导航: 数据库连接池 本地线程 上下文管理 面向对象部分知识点解析 1.子类继承父类__init__的三种方式 class Dog(Animal): #子类 派生类 def __init__(se ...

  3. Flask请求扩展和数据库连接池

    1.1.Flask之请求扩展 #!/usr/bin/env python # -*- coding:utf-8 -*- from flask import Flask, Request, render ...

  4. Flask中使用数据库连接池 DBUtils ——(4)

    DBUtils是Python的一个用于实现数据库连接池的模块. 此连接池有两种连接模式: 模式一:为每个线程创建一个连接,线程即使调用了close方法,也不会关闭,只是把连接重新放到连接池,供自己线程 ...

  5. Python数据库连接池---DBUtils

    Python数据库连接池DBUtils   DBUtils是Python的一个用于实现数据库连接池的模块. 此连接池有两种连接模式: 模式一:为每个线程创建一个连接,线程即使调用了close方法,也不 ...

  6. Python数据库连接池DBUtils

    Python数据库连接池DBUtils   DBUtils是Python的一个用于实现数据库连接池的模块. 此连接池有两种连接模式: 模式一:为每个线程创建一个连接,线程即使调用了close方法,也不 ...

  7. 基于DBUtils实现数据库连接池

    小知识: 1.子类继承父类的三种方式 class Dog(Animal): #子类 派生类 def __init__(self,name,breed, life_value,aggr): # Anim ...

  8. flask之基于DBUtils实现数据库连接池、本地线程、上下文

    本篇导航: 数据库连接池 本地线程 上下文管理 面向对象部分知识点解析 1.子类继承父类__init__的三种方式 class Dog(Animal): #子类 派生类 def __init__(se ...

  9. python之数据库连接池DBUtils

    DBUtils 是Python 的一个用于实现数据库连接池的模块. 此连接池有两种连接模式: DBUtils :提供两种外部接口: PersistentDB :提供线程专用的数据库连接,并自动管理连接 ...

  10. flask框架----数据库连接池

    数据库连接池 flask中是没有ORM的,如果在flask里面连接数据库有两种方式 一:pymysql 二:SQLAlchemy 是python 操作数据库的一个库.能够进行 orm 映射官方文档 s ...

随机推荐

  1. [TJOI/HEOI2016] 求和 题解

    为什么又是佳媛姐姐啊啊啊! 斯特林数在这道题中不好处理,直接拆开: \[f(n)=\sum_{i=0}^n\sum_{j=0}^i\begin{Bmatrix}i\\j\end{Bmatrix}2^j ...

  2. Deepin搭建git仓库服务gogs,debian也可用

    我尝试了gitlab.gitblit搭建均失败,deepin版本20.03 1. 步骤 访问gogs官网下载&安装页面 数据库(选择以下一项): MySQL:版本 >= 5.7. Pos ...

  3. windows设置定时任务

  4. Java进阶 - [1-5] 集合容器

    ArrayList add 1.先确认是否需要扩容,如果需要,则进行扩容操作ensureExplicitCapacity. 2.进行赋值 elementData[size++] = e; 扩容 1.如 ...

  5. 【Python】函数传参的方式

    学习笔记//20230402 edit 1.传参类型 值传递 引用传递 就像C++的参数传递: 值传递时值把实参的值传递给function, function 内对形参的修改不会影响实参; 引用传递时 ...

  6. angular+ionic项目,页面无法滚动的问题

    在做angular+ionic+cordova项目时,遇到一个小小的问题,就是内容做完,页面无法滚动,导致内容显示不完整 首先我检查了样式,发现并没有给页面定死高度,再次检查结构发现,我并没有用ion ...

  7. 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!

    前言 在人工智能技术日新月异的今天,DeepSeek-R1模型以其卓越的性能和广泛的应用场景,成为了众多用户心中的明星模型.它不仅具备强大的日常写作.翻译.问答等基础功能,更引入了独特的深度思考模式, ...

  8. Ubuntu如何下载nvidia驱动和Cuda Toolkit

    Ubuntu如何下载nvidia驱动和Cuda Toolkit 前言 ‍ 手快不小心把 nvidia​ 的某个东西删除了,现在不得不全部卸载后再重新安装了. 我再也不敢在不确认内容的情况下,确认删除了 ...

  9. Centos安装完成后,ifconfig:command not found

    1.问题:在刚最小安装完centos7,想查看本机IP地址.然后运行ifconfig,结果弹出报错. 2.问题排查:首先我们了解是不是没有开启网卡导致的?我们可以通过一下3种方法来排查: 1)通过pi ...

  10. Ansible管理密码库文件

    ansible可能需要访问密码或API密钥等敏感数据,以便能配置受管主机.通常,此信息可能以纯文本形式存储在清单变量或其他Ansible文件中.但若如此,任何有权访问Ansible文件的用户或存储,这 ...