flask之路【第二篇】蓝图与数据库连接
⚙️本教程工程文件{ProjectName}:Practice_flask_0618
{ProjectName}:Practice_flask_0619
六、蓝图
(视图函数特别多,为了分类,分文件放置视图函数)
蓝图用来构建业务功能可拆分的目录结构
-
工程项目目录结构
Practice_flask_0619/ ├── app.py # 主应用 ├── readme.md ├── Practice_flask_0619/ # 存放蓝图等各模板和模块的地方 │ ├── __init__.py # │ ├── views/ # 视图函数文件存放的地方,用蓝图将各个文件的视图函数注册到主程序去 | | ├──acount.py | | └──order.py │ ├── templates/ # 专属模板 │ │ └── auth/ │ │ └── login.html │ └── static/ #静态文件存放位置 | └── bootstrap5/ #利用bootstrap5优化网页显示 | ├── css/ | └── js/ └──── utils/ # 工具箱 └── db.py #建立数据库连接池 #标识包:当一个目录包含一个名为 __init__.py 的文件时,Python 就会将该目录视为一个包。即使 __init__.py 是空的,它也必须存在。
1蓝图的写法
各视图函数文件的蓝图写法:
# views\acount.py
from flask import Blueprint
ac_bp = Blueprint('acount', __name__)
@ac_bp.route('/order1')
def index():
return 'index'
@ac_bp.route('/order2')
def index2():
return 'index2'
主程序注册蓝图:
# __init__.py
# 实现 蓝图在主程序的注册
from flask import Flask
def create_app():
app = Flask(__name__)
app.config['SECRET_KEY'] = 'sdafj489955iixll'
from .views import acount
from .views import order
app.register_blueprint(acount.ac_bp)
# app.register_blueprint(acount.ac_bp, url_prefix='/account') 访问前加前缀/account,然后跟注册蓝图里的路由
app.register_blueprint(order.od_bp)
return app
# app.py
# 引用init.py文件实现flask功能
from Practice_flask_0619 import create_app
app = create_app()
if __name__ == '__main__':
app.run(debug=True)
✅总结
-
flask和django区别:flask 将请求request和session都放到上下文管理当中去了
-
flask的session以加密的形式保存在浏览器的cookie上,加密依赖secret_key
-
装饰器相关
- 编写装饰器,记得加functools
- 多个装饰器的应用,从下到上开始调用装饰器
4. 蓝图,保持好固定的目录结构。
七、数据库连接池
安装
pip install dbutils
pip install pymysql
使用
import pymsql
from DBUtils.Pooled_db import PooledDB
from pymysql import cursors
Pool = PooledDB(
creator = pymysql,
maxconnection = 6 , # 最大连接数,0和None表示不限制
mincached =2, # 初始化最少创建的链接,0表示不创建
blocking = True, #链接池中如果没有可用,等待
ping = 0, #ping mysql服务,检查服务是否可用 # 0,代表不去检查, 1当表当请求是检查
host = '1270.0.01',
port = 3306,
user = 'root',
password = 'My@20241103',
db = 'db_name',
charset = 'utf8mb4',
)
# 去连接池获取一个链接
conn = Pool.connection()
cursor = conn.cursor(cursor=cursors.DictCursor) #如果是这个返回的j将是字典
cursor.execute("select * from tb1 where id=%s and name=%s",(idvalue,namevalue))
result = cursor.fetchall()
cursor.close()
#将连接池放回到连接池(不关闭连接),如果不是连接池,下边的代码的作用将是关闭连接
conn.close()
使用线程,建立数据库连接测试
import pymsql
from DBUtils.Pooled_db import PooledDB
from pymysql import cursors
Pool = PooledDB(
creator = pymysql,
maxconnection = 6 , # 最大连接数,0和None表示不限制
mincached =2, # 初始化最少创建的链接,0表示不创建
blocking = True, #链接池中如果没有可用,等待
ping = 0, #ping mysql服务,检查服务是否可用 # 0,代表不去检查, 1当表当请求是检查
host = '1270.0.01',
port = 3306,
user = 'root',
password = 'My@20241103',
db = 'db_name',
charset = 'utf8mb4',
)
def task(num):
# 去连接池获取一个链接
conn = Pool.connection()
cursor = conn.cursor(cursor=cursors.DictCursor) #如果是这个返回的j将是字典
cursor.execute("select * from tb1 where id=%s and name=%s",(idvalue,namevalue))
result = cursor.fetchall()
cursor.close()
#将连接池放回到连接池(不关闭连接),如果不是连接池,下边的代码的作用将是关闭连接
conn.close()
print(num,">>>>>>>>>>",result)
#建立线程去执行
from threading import Thread
for i in range(57):#建立57个线程
t = Thread(target = task,args = (i,))
t.start()
-
通常将数据库连接这个功能放到单独的一个文件里去,然后需要的时候调用即可,具体使用参见《flask学习教程(一)中的utils/db.py文件》
-
另外,还可以基于类实现数据库连接db.py文件(上述都是基于函数):
# 因为只需要一个数据池子,所以类是单例模式 #:单利模式存在的目的是保证当前内存中仅存在单个实例,避免内存浪费! import pymysql from dbutils.pooled_db import PooledDB class SqlHelper(object): def __init__(self): self.Pool = PooledDB( creator = pymysql, maxconnection = 6 ,# 最大连接数,0和None表示不限制 mincached =2, # 初始化最少创建的链接,0表示不创建 blocking = True, #链接池中如果没有可用,等待 ping = 0, #ping mysql服务,检查服务是否可用 # 0,代表不去检查, 1当表当请求是检查 host = '1270.0.01', port = 3306, user = 'root', password = 'My@20241103', db = 'db_name', charset = 'utf8mb4', ) def fetchall(self,sql,*args): conn = self.Pool.connection() cursor = conn.cursor(cursor=cursors.DictCursor) #如果是这个返回的j将是字典 cursor.execute(sql,*args) result = cursor.fetchall() cursor.close() #将连接池放回到连接池(不关闭连接),如果不是连接池,下边的代码的作用将是关闭连接 conn.close() return result db = SqlHelper() db.fetchall("select * from tb1 where id=%s and name=%s",(idvalue,namevalue))
-
提取功能可以改成如下内容
# 因为只需要一个数据池子,所以类是单例模式
class SqlHelper(object):
def __init__(self):
self.Pool = PooledDB(
creator = pymysql,
maxconnection = 6 ,# 最大连接数,0和None表示不限制
mincached =2, # 初始化最少创建的链接,0表示不创建
blocking = True, #链接池中如果没有可用,等待
ping = 0, #ping mysql服务,检查服务是否可用 # 0,代表不去检查, 1当表当请求是检查
host = '1270.0.01',
port = 3306,
user = 'root',
password = 'My@20241103',
db = 'db_name',
charset = 'utf8mb4',
)
def open(self):
conn = self.Pool.connection()
cursor = conn.cursor(cursor=cursors.DictCursor) #如果是这个返回的j将是字典
return conn,cursor
def close(self,cursor,conn):
cursor.close()
conn.close()
def fetchall(self,sql,*args):
conn,cursor = self.open()
cursor.execute(sql,args)
result = cursor.fetchall()
self.close(conn,cursor)
return result
def fetchone(self,sql,*args):
conn,cursor = self.open()
cursor.execute(sql,args)
result = cursor.fetchone()
self.close(conn,cursor)
return result
db = SqlHelper()
db.fetchall("select * from tb1 where id=%s and name=%s",(idvalue,namevalue))