今日内容概要
- 蓝图
- flask-session
- 数据库连接池
今日内容详情
蓝图
1.蓝图blueprint:对程序进行目录结构划分
2.不用蓝图,划分目录--->一直使用app对象,会出现循环导入的问题
不用蓝图,划分目录
flask_day05
-templates
--order.html
-views
--__init__.py
--goods.py
--order.py
--user.py
-manage.py
manage.py
from views import app
if __name__ == '__main__':
app.run()
init.py
from flask import Flask
app = Flask(__name__,template_folder='../templates')
#不导入这个不行
from . import user
from . import order
from . import goods
goods.py
from . import app
@app.route('/goods')
def goods():
return 'goods'
order.py
from . import app
from flask import render_template
@app.route('/order')
def order():
return render_template('order.html')
user.py
from . import app
@app.route('/')
def home():
return 'home'
@app.route('/user')
def user():
return 'user'
使用蓝图
1.实例化得到一个蓝图对象 order_blue=Blueprint('order',__name__,template_folder='../templates')
2.以后注册路由,写请求扩展,都使用蓝图
@user_blue.before_request
@user_blue.route('/register')
3.在app中注册蓝图
from . import user
app.register_blueprint(user.user_blue) app.register_blueprint(user.user_blue,url_prefix='/user')
flask_day05
-templates
--order.html
-views
--__init__.py
--goods.py
--order.py
--user.py
-manage.py
manage.py
from views import app
if __name__ == '__main__':
app.run(port=8080)
init.py
from flask import Flask
# app = Flask(__name__,template_folder='../templates')
# app = Flask(__name__,static_folder='../static')
app = Flask(__name__)
app.debug = True
app.secret_key = 'asfasdfasdf'
#不导入这个不行
from . import user
from . import order
from . import goods
# 3.注册蓝图
app.register_blueprint(user.user_blue,url_prefix='/user') # 路由前缀
app.register_blueprint(order.order_blue,url_prefix='/order') # 路由前缀
user.py
from flask import Blueprint
# 1.首先实例华得到蓝图对象
user_blue = Blueprint('user',__name__)
# 2.其次注册路由
@user_blue.route('/')
def home():
return 'home'
@user_blue.route('/user')
def user():
return 'user'
order.py
from . import app
from flask import render_template,Blueprint
order_blue=Blueprint('order',__name__,template_folder='../templates',static_folder='../static')
@order_blue.route('/order')
def order():
return render_template('order.html')
order.html
<body>
<h1>order order</h1>
<img src="/order/static/7.jpg" alt="失败">
</body>
蓝图小项目
flask_blueprint_little # 项目名
-src # 核心文件
--__init__.py #包的inin里面实例化得到app对象
--views # 视图函数,类
---user.py
---order.py
--templates #模板
---user.html
--static #静态文件
-manage.py #启动文件
蓝图大型项目
Flask_session
1.flask 自带session--->以cookie的形式放到了浏览器中--->加密
2.真正的session,是在服务端存储
django中存在djangosession表中
flask中,使用第三方,保存在--->redis中--->flask-session
3.flask能不能用jwt--->能--->flask-session
4.使用:pip3 install flask-session
使用
方式一
1.pip3 install flask-session
#降一下flask版本即可
# 用高版本:在app中放一个参数 app.session_cookie_name='session'
1.使用方式一:
from flask_session import RedisSessionInterface
app.session_cookie_name='session'
app.session_interface=RedisSessionInterface(redis=None,key_prefix='lqz') # 动态替换,把原来的session对象换成放到redis的session对象
# 4 以后再使用session,就会存到redis中了
session.get()
session[]=value赋值
from flask import Flask,session
# 1.导入类
from flask_session import RedisSessionInterface
app = Flask(__name__)
app.debug = True
app.secret_key = 'sdsfcdzfcsfvc'
# 2.实例话得到对象
# 3.把实例化得到的对象,赋值给app.session_interface
import redis
conn = redis.Redis(host='127.0.0.1', port=6379)
app.session_interface=RedisSessionInterface(redis=conn, key_prefix='nana') # 动态替换,把原来的session对象换成放到redis的session对象
# 4 以后再使用session,就会存到redis中了
@app.route('/')
def index():
session['name']="luona"
return 'index'
@app.route('/home')
def home():
print(session['name'])
return 'home'
if __name__ == '__main__':
app.run()
使用方式二:
from redis import Redis
from flask_session import Session
app.session_cookie_name = 'session'
app.config['SESSION_TYPE'] = 'redis'
app.config['SESSION_REDIS'] = Redis(host='127.0.0.1',port='6379')
Session(app)
from flask import Flask,session
app = Flask(__name__)
app.debug = True
app.secret_key = 'sdsfcdzfcsfvc'
from redis import Redis
from flask_session import Session
# app.session_cookie_name = 'session'
app.config['SESSION_TYPE'] = 'redis'
app.config['SESSION_REDIS'] = Redis(host='127.0.0.1',port='6379')
Session(app)
# 4 以后再使用session,就会存到redis中了
@app.route('/')
def index():
session['name']="cx"
return 'index'
@app.route('/home')
def home():
print(session['name'])
return 'home'
if __name__ == '__main__':
app.run()
数据库连接池
flask--->数据库--->原生操作--->pymsql
1.安装:DBUtils
2.使用 类创建一个池对象
PYMYSQL_POOL = PooledDB(
creator=pymysql, # 使用链接数据库的模块
maxconnections=2, # 连接池允许的最大连接数,0和None表示不限制连接数
mincached=1, # 初始化时,链接池中至少创建的空闲的链接,0表示不创建
maxcached=0, # 链接池中最多闲置的链接,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='123',
database='cars',
charset='utf8'
)
3.从池对象中,取出一个链接使用
conn = PYMYSQL_POOL.connection()
4.flask中使用
@app.route('/')
def index():
conn = PYMYSQL_POOL.connection() # 从池中拿一个链接
cursor = conn.cursor(cursor=DictCursor) # 默认元组套元组,设置DictCursor就是列表套字典
cursor.execute('select id,title from news where id<10')
res1 = cursor.fetchall()
cursor.close()
conn.close()
return jsonify(res1)
flask数据库操作
from flask import Flask,jsonify
import pymysql
app = Flask(__name__)
app.debug = True
app.secret_key = 'sdsfcdzfcsfvc'
from pymysql.cursors import DictCursor
@app.route('/')
def index():
# 1.conn连接的创建,放到函数里面,否则会数据错乱
conn = pymysql.connect(
user='root', # The first four arguments is based on DB-API 2.0 recommendation.
password="ln1998151125",
host='127.0.0.1',
database='jingdong',
unix_socket=None,
port=0,
)
curser = conn.cursor(cursor=DictCursor) # # 默认元组套元组,设置DictCursor就是列表套字典
curser.execute('select * from test where id<10')
res = curser.fetchall()
print(res)
curser.close()
conn.close()
return jsonify(res)
if __name__ == '__main__':
app.run()
1.conn和Cursor是全局--->会出数据错乱,详情看图
2.conn和Cursor要在视图函数中--->独立生成--->django,执行一个orm--->创建一个链接,执行,执行完释放链接--->假设并发数很高--->需要使用数据库连接池
数据库连接池
无连接池
from threading import Thread
import pymysql
from pymysql.cursors import DictCursor
import time
import random
# 无连接池
def task():
conn = pymysql.connect(
user='root', # The first four arguments is based on DB-API 2.0 recommendation.
password="123",
host='127.0.0.1',
database='jingdong',
unix_socket=None,
port=0,
)
curser = conn.cursor(cursor=DictCursor) # # 默认元组套元组,设置DictCursor就是列表套字典
time.sleep(random.randint(0,2))
curser.execute('select * from test where id<10')
res = curser.execute("show status like 'Threads%'")
curser.fetchall()
print(res)
curser.close()
conn.close()
l =[]
for i in range(300):
t = Thread(target=task)
t.start()
l.append(t)
for i in l:
l.join()
连接池
Pool.py
from dbutils.pooled_db import PooledDB
import pymysql
# 池大小为6的数据库连接池---》
PYMYSQL_POOL = PooledDB(
creator=pymysql, # 使用链接数据库的模块
maxconnections=2, # 连接池允许的最大连接数,0和None表示不限制连接数
mincached=1, # 初始化时,链接池中至少创建的空闲的链接,0表示不创建
maxcached=0, # 链接池中最多闲置的链接,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='123',
database='jingdong',
charset='utf8'
)
from flask import Flask,jsonify
import pymysql
from pymysql.cursors import DictCursor
from pool import PYMYSQL_POOL
#
app = Flask(__name__)
app.debug = True
app.secret_key = 'sdsfcdzfcsfvc'
@app.route('/')
def index():
conn = PYMYSQL_POOL.connection() # 从池中拿一个链接
cursor = conn.cursor(cursor=DictCursor) # 默认元组套元组,设置DictCursor就是列表套字典
cursor.execute('select * from test where id<10')
res1=cursor.fetchall()
cursor.execute("show status like 'Threads%'")
res = cursor.fetchall()
print(res)
cursor.close()
conn.close()
return jsonify(res1)
@app.route('/no_pool')
def home():
conn = pymysql.connect(
user='root',
password="ln1998151125",
host='127.0.0.1',
port=3306,
database='jingdong')
cursor = conn.cursor(cursor=DictCursor) # 默认元组套元组,设置DictCursor就是列表套字典
cursor.execute('select * from test where id<10')
res1 =cursor.fetchall()
cursor.execute("show status like 'Threads%'")
res = cursor.fetchall()
print(res,'---')
cursor.close()
conn.close()
return jsonify(res1)
if __name__ == '__main__':
app.run()
request并发请求
from threading import Thread
import requests
def task():
# res = requests.get('http://127.0.0.1:5000')
"""
[{'Variable_name': 'Threads_cached', 'Value': '9'}, {'Variable_name': 'Threads_connected', 'Value': '7'}, {'Variable_name': 'Threads_created', 'Value': '691'}, {'Variable_name': 'Threads_running', 'Value': '4'}]
:return:
"""
res = requests.get('http://127.0.0.1:5000/no_pool')
"""
[{'Variable_name': 'Threads_cached', 'Value': '9'}, {'Variable_name': 'Threads_connected', 'Value': '9'}, {'Variable_name': 'Threads_created', 'Value': '714'}, {'Variable_name': 'Threads_running', 'Value': '2'}] ---
"""
print(len(res.text))
if __name__ == '__main__':
for i in range(500):
t = Thread(target=task)
t.start()