Flask入门day02(完整版)

80 阅读5分钟

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的编写

  1. sqlhelper介绍

    sqlhelper 是自己编写或者从第三方库中导入的模块,用于执行 SQL 数据库操作的帮助工具。通常情况下,它封装了数据库连接、执行查询、获取结果等操作,以简化代码并提高代码的可维护性。

  2. 基于函数来编写

    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 result
    
    import 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()
    
  3. 基于类来编写

    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 result
    
    from 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 上下文管理

  1. 在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!'