P13 今日概要
- 数据库连接池
- flask配置
- flask路由
- before_request/after_request
P14 day1内容回顾
- flask与django的区别?
- django与flask哪个好?
- django的app与flask的蓝图区别
- 装饰器的应用
P15—P16 面试题讲解
P17 数据库连接池
17.1 初级阶段——pymysql连接数据库(mysql为例)
def fetchall(sql): #对连接数据库功能进行封装
#导包
import pymysql
#1.创建连接
conn = pymysql.connect(
host='localhost', # 数据库主机地址
port=3306, # 数据库端口号
user='username', # 数据库用户名
password='password', # 数据库密码
database='dbname', # 数据库名称
)
#2.创建游标
cursor = conn.cursor()
#3.执行sql
cursor.execute(sql)
#4.获取执行sql后返回的所有数据
result = cursor.fetchall()
#5.提交,不然无法保存新建或修改的数据(获取数据不用执行该步骤)
conn.commit()
#6.关闭游标
cursor.close()
#7.关闭连接
CONN=close()
#返回执行sql的结果
return result
17.2 高级阶段——数据库连接池
# 1.安装
# pip install dbutils
# 2.使用
import pymysql
from dbutils.pooled_db import PooledDB
pool = PooledDB(
creator=pymysql, # 使用 PyMySQL 作为连接池创建的对象(表示底层用pymysql来连接数据库)
maxconnections=10, # 连接池所允许的最大连接数,0和none表示不限制连接数
mincached=2, # 初始化时,连接池中至少创建的空闲的连接的个数,0表示不创建(初始化时是不会创建连接的)
blocking=True, # 如果连接池中没有可用连接,是否阻塞等待连接。True,等待;False,不等待然后报错;
ping=0, # ping Mysql服务端,检查服务是否可用。如0=None=never(表示永远不ping),1=default=when it is requested(表示发请求时ping一次),2=when a cursor is created(创建游标后ping一下),4=when a query is executed(执行sql后ping一下),7=always(每个环节都会ping)
#同pymysql连接数据库
host='localhost', # 数据库主机地址
port=3306, # 数据库端口号
user='username', # 数据库用户名
password='password', # 数据库密码
database='dbname', # 数据库名称
charset='utf8mb4' # 字符集
)
# 去连接池中获取一个连接
conn = pool.connection()
#创建游标
cursor = conn.cursor()
#执行sql
cursor.execute('select * from tb_student')
#sql的执行结果
result = cursor.fetchall()
#关闭游标
cursor.close()
#将连接放回连接池中
conn.close()
#打印结果
print(result)
多线程测试连接池
import pymysql
from dbutils.pooled_db import PooledDB
pool = PooledDB(
creator=pymysql, # 使用 PyMySQL 作为连接池创建的对象(表示底层用pymysql来连接数据库)
maxconnections=10, # 连接池所允许的最大连接数,0和none表示不限制连接数
mincached=2, # 初始化时,连接池中至少创建的空闲的连接的个数,0表示不创建(初始化时是不会创建连接的)
blocking=True, # 如果连接池中没有可用连接,是否阻塞等待连接。True,等待;False,不等待然后报错;
ping=0, # ping Mysql服务端,检查服务是否可用。如0=None=never(表示永远不ping),1=default=when it is requested(表示发请求时ping一次),2=when a cursor is created(创建游标后ping一下),4=when a query is executed(执行sql后ping一下),7=always(每个环节都会ping)
#同pymysql连接数据库
host='localhost', # 数据库主机地址
port=3306, # 数据库端口号
user='root', # 数据库用户名
password='123456', # 数据库密码
database='db_jsu', # 数据库名称
charset='utf8mb4' # 字符集
)
def task(num):
# 去连接池中获取一个连接
conn = pool.connection()
# 创建游标
cursor = conn.cursor()
# 执行sql
#cursor.execute('select * from tb_student')
cursor.execute('select sleep(3)')
# sql的执行结果
result = cursor.fetchall()
# 关闭游标
cursor.close()
# 将连接放回连接池中
conn.close()
print(num, '-------------->',result)
#导入多线程
from threading import Thread
for i in range(57):
t = Thread(target=task,args=(i,))
t.start()
P18 sqlhelper的编写
-
sqlhelper介绍
sqlhelper 是自己编写或者从第三方库中导入的模块,用于执行 SQL 数据库操作的帮助工具。通常情况下,它封装了数据库连接、执行查询、获取结果等操作,以简化代码并提高代码的可维护性。
-
基于函数来编写
import pymysql from dbutils.pooled_db import PooledDB #创建连接池 POOL = PooledDB( creator = pymysql, maxconnections = 6, mincached = 2, blocking = True, ping =0, host = '127.0.0.1', port = 3306, user = 'root', password = '123456', database = 'db_jsu', charset = 'utf8' ) def open_conn(sql,*args): # 连接池获取连接 conn = POOL.connection() # 获取游标 cursor = conn.cursor() #用游标执行sql cursor.execute(sql,args) #返回 return cursor,conn def close_conn(cursor,conn): # 关闭游标 cursor.close() # 将连接放回到连接池 conn.close() #获取所有数据 def fetchall(sql,*args): cursor,conn = open_conn(sql,*args) #获取sql结果 result = cursor.fetchall() #关闭 close_conn(cursor,conn) #返回数据 return result #获取单条数据 def fetchone(sql,*args): cursor,conn = open_conn(sql,*args) result = cursor.fetchone() close_conn(cursor, conn) return resultimport sqlhelper from flask import Flask app = Flask(__name__) @app.route('/login') def login(): result = sqlhelper.fetchone('select * from tb_student where username=%s ','xiaoyu') print(result) return 'login' @app.route('/index') def index(): result = sqlhelper.fetchall('select * from tb_teacher') print(result) return 'index' @app.route('/order') def order(): pass if __name__ == '__main__': app.run() -
基于类来编写
from dbutils.pooled_db import PooledDB import pymysql class SqlHelper(object): def __init__(self): self.pool = PooledDB( creator=pymysql, maxconnections=6, mincached=2, blocking=True, ping=0, host='127.0.0.1', port=3306, user='root', password='123456', database='db_jsu', charset='utf8' ) def open(self): conn = self.pool.connection() cursor = conn.cursor() return cursor, conn def close(self,cursor,conn): cursor.close() conn.close() def fetchall(self, sql, *args): cursor, conn = self.open() cursor.execute(sql, args) result = cursor.fetchall() self.close(cursor,conn) return result def fetchone(self,sql,*args): cursor, conn = self.open() cursor.execute(sql, args) result = cursor.fetchone() self.close(cursor, conn) return resultfrom flask import Flask import sqlhelper2 app = Flask(__name__) db = sqlhelper2.SqlHelper() @app.route('/login') def login(): result = db.fetchone('select * from tb_student where username=%s ','xiaoyu') print(result) return 'login' @app.route('/index') def index(): result = db.fetchall('select * from tb_teacher') print(result) return 'index' @app.route('/order') def order(): pass if __name__ == '__main__': app.run()
P19 上下文管理
- 在with obj as f 中,如果obj是一个对象,那么会执行obj对象中的enter方法,该方法的返回值就是f的值。当with...as..中的内部代码执行完后,执行该对象的exit方法,该方法执行完后,代码终止。
class Foo(object):
def __enter__(self):
return '123'
def __exit__(self, exc_type, exc_val, exc_tb):
pass
obj = Foo()
with obj as f:
print(f)
class Foo(object):
def do_something(self):
print('I am doing sth!')
def close(self):
pass
class Context:
def __enter__(self):
self.data = Foo()
return self.data
def __exit__(self, exc_type, exc_val, exc_tb):
self.data.close()
with Context() as ctx:
ctx.do_something() #打印结果为'I am doing sth!'