Flask快速入门day 03(蓝图的使用,g对象,数据库连接池)

Flask框架

一、蓝图-blueprint

简介:

blueprint(蓝图)在flask项目中用来组织管理和注册视图函数的路由

蓝图实际可以理解为是一个存储一组视图方法的容器对象,其具有如下特点:

  • 1、一个应用可以具有多个蓝图,可以将一个蓝图注册到任何一个未使用的URL下比如 “/user”、“/goods”

  • 2、可以单独具有自己的模板、静态文件或者其它的通用操作方法,它并不是必须要实现应用的视图和函数的

  • 3、在一个应用初始化时,就应该要注册需要使用的蓝图

  • 4、蓝图并不是一个完整的应用,它不能独立于应用运行,而必须要注册到某一个应用中

1、蓝图的用法

- 1、在需要被注册的app文件,或py文件下导入
    from flask import Blueprint
    
- 2、实例化蓝图
    #  第一个参数视图别名
    #  第二个参数模块别名
    #  第三、四参数指定静态文件和模板路径
    user_bp = Blueprint('user', __name__, static_folder='static', template_folder='templates')

- 3、在视图函数上装饰实例化的蓝图对象(不再直接使用flask实例化对象)
    @user_bp.route('/', endpoint='index')
    def index():
        return 'index view'

- 4、使用falsk实例化的对象管理蓝图并注册路由
    # 导入管理app的蓝图实例化对象
    from .user import user_bp

    # 注册路由 管理实例化的蓝图对象
    app.register_blueprint(user_bp, url_prefix='/user')

2、蓝图规划目录

不使用蓝图规划目录:

# 不使用蓝图规划目录容易造成循环导入
    -falsk  # 项目文件
       -src  # 存放核心文件
            __init__.py  # 用于实例化flask,导入views
            models.py  # 用于创建表模型
            views.py  # 视图文件
        -static  # 静态文件
        -templates  # 模板文件
            index.html  # 模板
        -manage.py  # 项目启动文件

image-20230404185953214

使用蓝图规划目录(小型项目):

# 使用蓝图,划分小型项目目录
    little_blueprint              # 项目名
        -src                      # 核心代码
            -static               # 静态文件
                -1.jpg            # 图片
            -templates            # 模板文件
            -user.html            # 模板
            -views                # 视图函数存放位置
                -order.py         # 订单相关视图
                -user.py          # 用户相关视图
            -__init__.py          # 包
            -models.py            # 表模型
        -manage.py                # 启动文件

使用蓝图规划目录(大型项目):

falsk  # 项目文件
    src  # 核心文件
        home  # 首页app
        order  # 订单app
        user  # 用户app
            static  # app下静态文件文件
            templates  # app下模板文件
            __init__.py  # 包(注册蓝图,管理app的地方)
            models.py  # app下表模型文件
            views.py  # 视图函数文件
    __init__.py  # 项目包文件(管理app,注册路由分发的地方)
    settings.py  # 项目配置文件
    manage.py  # 项目启动文件

image-20230404194030936

二、g对象

简介:

  • g对象:

    • global的缩写,在python中是个关键字,不能以关键字作为变量名,干脆用了g

    • g对象,在整个请求的全局,可以放值,可以取值

    • g对象是flask提供的一个用于当初请求下的上下文,可以在当此请求下将一个对象或变量存入g对象,就可以在当此请求下的任何地方直接使用

  • 为什么不直接使用request对象:

    • 为例避免污染request中的方法

1、使用方法

- 1、 导入g对象
	from flask import g

- 2、存入
	# 直接使用‘点的’方式存入
	g.name = name
	
- 3、取
	# 直接使用‘点’取值
	g.name

2、使用案例

from . import user_bp
from flask import request, g


# g对象的存取
@user_bp.route('/', endpoint='index')
def index():
    # 获取get请求携带的name,存入g中然后在return出存入的值
    name = request.args.get('name')
    # 存入
    g.name = name
    # 取出
    return g.name


@user_bp.route('/get', endpoint='get_name')
def get_name():
    # 当次请求并没有存入,所以会直接报错
    return g.name

三、数据库连接池

简介:

  • 什么是连接池:
    • 简单来说,类似于一个池塘,池塘的大小决定池塘内鱼儿的数量,也就是操作请求数据库的数量,每个人的请求都是一条新的链接
  • 为什么要用连接池:
    • 如果在视图函数内直接使用pymysql,那么每次请求都会建立一条新的数据库链接,使用连接池可以控制链接建立的链接数量
  • 直接在全局建立链接可以吗:
    • 不可以,直接在全局建立一条数据库连接的话,这样所有的请求都会使用这一条链接,假如a发起了一条seletc查询user数据库,在返回数据前b也使用了seletc查询order数据,这样a返回的数据就会变成b查询的结果,照成数据混乱
  • 连接池解决的问题:
    • 每次进入视图函数,从池中取一个连接使用,使用完放回到池中,只要控制池的大小,就能控制mysql连接数

1、不使用池

import pymysql


@user_bp.route('/', endpoint='index')
def index():
    # 实例化pymysql
    conn = pymysql.connect(user='root',
                           password="123",
                           host='127.0.0.1',
                           database='big_cabbage1',
                           port=3306)
    # 产生游标对象(参数指定返回的格式是字典,默认是元组)
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    # 查询数据库
    cursor.execute('select * from user limit 2')
    # 获取全部的查询数据
    res = cursor.fetchall()
    return jsonify(res)

2、使用连接池

# 使用第三方数据库连接池,使用步骤
    -1 安装 pip install dbutils
    -2 使用:实例化得到一个池对象
    -3 在视图函数中导入使用
        from dbutils.pooled_db import PooledDB
        import pymysql
        pool = PooledDB(
            creator=pymysql,  # 使用链接数据库的模块
            maxconnections=10,  # 连接池允许的最大连接数,0和None表示不限制连接数
            mincached=2,  # 初始化时,链接池中至少创建的空闲的链接,0表示不创建
            maxcached=5,  # 链接池中最多闲置的链接,0和None不限制
            maxshared=3,
            # 链接池中最多共享的链接数量,0和None表示全部共享。PS: 无用,因为pymysql和MySQLdb等模块的 threadsafety都为1,所有值无论设置为多少,_maxcached永远为0,所以永远是所有链接都共享。
            blocking=True,  # 连接池中如果没有可用连接后,是否阻塞等待。True,等待;False,不等待然后报错
            maxusage=None,  # 一个链接最多被重复使用的次数,None表示无限制
            setsession=[],  # 开始会话前执行的命令列表。如:["set datestyle to ...", "set time zone ..."]
            ping=0,
            # ping MySQL服务端,检查是否服务可用。# 如:0 = None = never, 1 = default = whenever it is requested, 2 = when a cursor is created, 4 = when a query is executed, 7 = always
            host='127.0.0.1',
            port=3306,
            user='root',
            password='',
            database='cnblogs',
            charset='utf8'
        )
                      
        
#  带池的代码
@app.route('/article_pool')
def article_pool():
    conn = pool.connection()
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    cursor.execute('select id,title,author_img from aritcle limit 2')
    res = cursor.fetchall()
    print(res)
    return jsonify(res)

3、压力测试

# 压力测试代码
from threading import Thread
import requests


def task():
    res = requests.get('http://127.0.0.1:5000/article_pool')
    print(len(res.text))


if __name__ == '__main__':
    for i in range(500):
        t = Thread(target=task)
        t.start()
## 效果是:
	使用池的连接数明显小
    不使用池连接数明显很大
    
    
# 查看数据库连接数
show status like 'Threads%'
posted @ 2023-04-10 21:55  kangshong  阅读(111)  评论(0编辑  收藏  举报