目录

一:g对象

  • 简介

1.专门用来存储用户信息的g对象,g的全称的为global,g对象是全局的
2.g对象在一次请求中的所有的代码的地方,都是可以使用的,g对象在当次请求中一直有效

1.g对象和session的区别

1.session对象是可以跨request的,只要session还未失效,不同的request的请求会获取到同一个session,
2.但是g对象不是,g对象不需要管过期时间,请求一次就g对象就改变了一次,或者重新赋值了一次
2.g对象实战代码
from flask import Flask,g,request,session

app = Flask(__name__)

@app.before_request
def first():
session['name']='dlrb'
request.form='egon'
g.name='lqz' @app.after_request
def after(response):
print('11111',g.name)
return response @app.route('/')
def hello_world():
print('00000',g.name)
return 'Hello World!' if __name__ == '__main__':
app.run()

二:flask-session(借助于第三方插件连接redis保存session )

作用:将默认保存的签名cookie中的值 保存到 redis/memcached/file/Mongodb/SQLAlchemy

安装:pip3 install flask-session

1.方式一:

from flask import Flask,g,request,session

from flask_session import RedisSessionInterface
app = Flask(__name__) app.debug=True # 开启debug,没上线为True,方便查询错误 app.secret_key='asdfasdfasdf' # 密钥
# 方式一
from redis import Redis
conn=Redis(host='127.0.0.1',port=6379) # 使用第三方查询RedisSessionInterface进行将session存入redis
app.session_interface=RedisSessionInterface(redis=conn,key_prefix='flask_session')
# redis : redis地址,端口(不填,默认本地)
# key_prefix : 前缀 @app.route('/')
def hello_world():
session['name']='lqz'
return 'Hello World!' if __name__ == '__main__':
app.run()

2.方式二(flask使用第三方插件的通用方案):

from flask_session import Session
from redis import Redis
app.config['SESSION_TYPE'] = 'redis'
app.config['SESSION_KEY_PREFIX']='flask_session'
app.config['SESSION_REDIS'] = Redis(host='127.0.0.1',port='6379')
Session(app) # 将app传入session内 @app.route('/')
def hello_world():
session['name']='lqz'
return 'Hello World!' if __name__ == '__main__':
app.run()

3.效果1:(访问地址浏览器生成session)

4.效果2:(session存入redis)

5.如何设置session的过期时间?

#源码expires = self.get_expiration_time(app, session)
'PERMANENT_SESSION_LIFETIME': timedelta(days=31),#这个配置文件控制

6.设置cookie时,如何设定关闭浏览器则cookie失效

app.session_interface=RedisSessionInterface(conn,key_prefix='lqz',permanent=False)  # permanent=False  的情况下就会关闭浏览器,cookie失效

三:数据库连接池

1.pymsql链接数据库

from flask import Flask
import time
import pymysql
app = Flask(__name__)
app.debug=True app.secret_key='asdfasdfasdf' @app.route('/')
def hello_world():
# pymysql连接数据库(指定数据库信息)
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', password='1', database='luffy')
cursor = conn.cursor() # 获得游标对象
cursor.execute('select * from luffy_order') # 查询luffy_order表
time.sleep(1)
print(cursor.fetchall()) # 获取所有
return 'Hello World!' if __name__ == '__main__':
app.run()

2.问题:

# 问题:
1.如果使用全局连接对象,会导致数据错乱
# 问题二:
2.如果在视图函数中创建数据库连接对象,会导致连接数过多

3.解决:

使用数据库连接池  DBUtils

4.数据库连接池版

from dbutils.pooled_db import PooledDB
import pymysql POOL=PooledDB(
creator=pymysql, # 使用链接数据库的模块
maxconnections=6, # 连接池允许的最大连接数,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='1',
database='luffy',
charset='utf8') # 导入进程
from threading import Thread def task():
# 去池中获取连接
conn = POOL.connection()
# 获取游标
cursor = conn.cursor()
cursor.execute('select * from luffy_order') # 查询luffy_order表
print(cursor.fetchall()) # 获取所有
for i in range(100): # 循环100个进程
t=Thread(target=task) # 进程执行
t.start() # mysql可以看到当前有多少个连接数

四:信号

# Flask框架中的信号基于blinker,其主要就是让开发者可是在flask执行过程中定制一些用户行为

1.内置信号

# pip3 install blinker

## flask中有内置信号
# 什么时候触发的
request_started = _signals.signal('request-started') # 请求到来前执行
request_finished = _signals.signal('request-finished') # 请求结束后执行 before_render_template = _signals.signal('before-render-template') # 模板渲染前执行
template_rendered = _signals.signal('template-rendered') # 模板渲染后执行 got_request_exception = _signals.signal('got-request-exception') # 请求执行出现异常时执行 request_tearing_down = _signals.signal('request-tearing-down') # 请求执行完毕后自动执行(无论成功与否)
appcontext_tearing_down = _signals.signal('appcontext-tearing-down')# 应用上下文执行完毕后自动执行(无论成功与否) appcontext_pushed = _signals.signal('appcontext-pushed') # 应用上下文push时执行
appcontext_popped = _signals.signal('appcontext-popped') # 应用上下文pop时执行
message_flashed = _signals.signal('message-flashed') # 调用flask在其中添加数据时,自动触发

2.内置信号的使用

3.内置信号使用步骤:

1.写一个函数
2.跟内置信号绑定
3.以后只要触发内置信号,函数就会执行
from flask import Flask,signals,render_template
from flask.signals import _signals
app = Flask(__name__) # 往信号中注册函数
def func(*args,**kwargs):
print('触发型号',args,kwargs)
# 信号一般用来记录日志
# signals信号.内置信号(请求到来前执行).connect(执行函数)
signals.request_started.connect(func) # 给模板渲染前编写信号
def template_before(*args,**kwargs):
print(args)
print(kwargs)
print('模板开始渲染了')
# signals信号.内置信号(模板渲染前执行).connect(执行函数)
signals.before_render_template.connect(template_before)

4.自定义信号

5.自定制信号流程

1 写一个信号
2 写一个函数
3 信号绑定函数
4 触发信号
# 自定义信号
# 自定制信号 = signals.signal('自定制信号名称')
before_view = _signals.signal('before_view') # 写函数
def test(*args,**kwargs):
print('我执行了')
print(args)
print(kwargs) # 绑定给信号
# before_view信号.connect(执行函数)
before_view.connect(test) @app.route('/index',methods=['GET',"POST"])
def index1():
# 触发信号
# before_view信号.send发送(关键字,关键字)
before_view.send(name='lqz',age=19)
print('视图')
return render_template('index.html',a='lqz') if __name__ == '__main__':
app.run(port=8080)
app.__call__

五:flask-script

# 1.用于实现类似于django中 python3 manage.py runserver ...类似的命令

1.安装

pip3 install flask-script

2.文件名称(启动的manage.py):

manage.py
from flask_script import Manager
from flask import Flask
app = Flask(__name__) # 传入app生成flask_script对象
manager=Manager(app) if __name__ == '__main__':
manager.run()
#python3 manage.py runserver --help

以后执行(启动)直接:python3 manage.py runserver

3.自定制命令

@manager.command
def custom(arg):
"""
自定义命令
python manage.py custom 123
:param arg:
:return:
"""
print(arg) @manager.option('-n', '--name', dest='name')
@manager.option('-u', '--url', dest='url')
def cmd(name, url):
"""
自定义命令(-n也可以写成--name)
执行: python manage.py cmd -n lqz -u http://www.oldboyedu.com
执行: python manage.py cmd --name lqz --url http://www.oldboyedu.com
:param name:
:param url:
:return:
"""
print(name, url)

4.自定制有什么用?

1.可以把excel的数据导入数据库,定制个命令,去执行

六:SQLAlchemy(orm框架)

1.orm框架SQLAlchemy,第三方,独立使用,集成到web框架中
2.django的orm框架

1.安装SQLAlchemy

pip install SQLAlchemy

2.sqlalchemy执行ORM

from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine
from models import Book,Hobby,Person # 指定create_engine对象,sqlalchemy指定数据库
engine = create_engine("mysql+pymysql://root:1@127.0.0.1:3306/aaa", max_overflow=0, pool_size=5) # 连接池大小 # bind绑定engine
# 生成Connection对象
Connection = sessionmaker(bind=engine) # 每次执行数据库操作时,都需要创建一个Connection
con = Connection() # ############# 执行ORM操作 #############
# 单表插入一条数据
# book=Book(name='金',price=11)
# con.add(book) ## 一对多关系插入
# hobby=Hobby(caption='足球')
# person=Person(name='lqz',hobby_id=1)
# con.add(hobby)
# con.add(person) # 一对多插入 # hobby=Hobby(caption='橄榄球')
# person=Person(name='egon',hobby=hobby)
# con.add(hobby)
# con.add(person) # 查询egon
# egon=con.query(Person).filter_by(name='egon').first()
# print(egon.hobby_id)
# print(egon.hobby.caption) # 拿到hobby对象 ,正向查询:字段名 glq=con.query(Hobby).filter_by(caption='橄榄球').first()
pers=glq.pers #反向查询,按 backref='pers'
print(pers)
for p in pers:
print(p.name) # 提交事务
con.commit()
# 关闭session,其实是将连接放回连接池
con.close()

3.models模型层

import datetime
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, Text, ForeignKey, DateTime, UniqueConstraint, Index
from sqlalchemy.orm import relationship
Base = declarative_base() class Users(Base): # Base基类(相当于Django中的models.MODELS)
__tablename__ = 'users' # 数据库表名称
id = Column(Integer, primary_key=True) # id 主键
name = Column(String(32), index=True, nullable=False) # name列,索引,不可为空
email = Column(String(32), unique=True)
#datetime.datetime.now不能加括号,加了括号,以后永远是当前时间
ctime = Column(DateTime, default=datetime.datetime.now)
extra = Column(Text, nullable=True) __table_args__ = (
# id和name (联合唯一名称:uix_id_name)
UniqueConstraint('id', 'name', name='uix_id_name'),
# name和email是联合索引 索引名称(ix_id_name)
Index('ix_id_name', 'name', 'email'), #索引
) class Book(Base): # 表模型
__tablename__ = 'books'
id = Column(Integer, primary_key=True)
name = Column(String(32), index=True, nullable=False)
price=Column(Integer) # 一对多关系
class Hobby(Base): # 表模型
__tablename__ = 'hobby'
id = Column(Integer, primary_key=True)
caption = Column(String(50), default='篮球') class Person(Base):
__tablename__ = 'person'
nid = Column(Integer, primary_key=True)
name = Column(String(32), index=True, nullable=True)
# hobby指的是tablename而不是类名,uselist=False
hobby_id = Column(Integer, ForeignKey("hobby.id")) # 外键 # 跟数据库无关,不会新增字段,只用于快速链表操作
# 类名,backref用于反向查询
hobby = relationship('Hobby', backref='pers')
def init_db():
"""
根据类创建数据库表
:return:
"""
engine = create_engine(
"mysql+pymysql://root:1@127.0.0.1:3306/aaa?charset=utf8",
max_overflow=0, # 超过连接池大小外最多创建的连接
pool_size=5, # 连接池大小
pool_timeout=30, # 池中没有线程最多等待的时间,否则报错
pool_recycle=-1 # 多久之后对线程池中的线程进行一次连接的回收(重置)
) Base.metadata.create_all(engine) def drop_db():
"""
根据类删除数据库表
:return:
"""
engine = create_engine(
"mysql+pymysql://root:1@127.0.0.1:3306/aaa?charset=utf8",
max_overflow=0, # 超过连接池大小外最多创建的连接
pool_size=5, # 连接池大小
pool_timeout=30, # 池中没有线程最多等待的时间,否则报错
pool_recycle=-1 # 多久之后对线程池中的线程进行一次连接的回收(重置)
) Base.metadata.drop_all(engine) if __name__ == '__main__':
# drop_db() # 删除表
init_db() # 创建表模型

Flaks框架(g对象,session,数据库连接池,信号,flask-script,SQLAlchemy(ORM))的更多相关文章

  1. springboot activiti 整合项目框架源码 druid 数据库连接池 shiro 安全框架

    官网:www.fhadmin.org 工作流模块---------------------------------------------------------------------------- ...

  2. 基于DBUtils实现数据库连接池及flask项目部署

    阅读目录 flask中是没有ORM的,如果在flask里面连接数据库有两种方式 数据库连接池原理 模式一: 模式二: 数据库连接池 flask中是没有ORM的,如果在flask里面连接数据库有两种方式 ...

  3. java web学习总结(十六) -------------------数据库连接池

    一.应用程序直接获取数据库连接的缺点 用户每次请求都需要向数据库获得链接,而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长.假设网站一天10万访问量,数据库服务器就需要创建10万次连接,极大 ...

  4. [数据库连接池二]Java数据库连接池--C3P0和JDNI.

    前言:上一篇文章中讲了DBCP的用法以及实现原理, 这一篇再来说下C3P0和JDNI的用法. 1.1.C3P0数据源 C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规 ...

  5. Java数据库连接池详解

    http://www.javaweb1024.com/java/JavaWebzhongji/2015/06/01/736.html 对于共享资源,有一个很著名的设计模式:资源池(Resource P ...

  6. hibernate框架学习之Session管理

    Session对象的生命周期 lHibernate中数据库连接最终包装成Session对象,使用Session对象可以对数据库进行操作. lSession对象获取方式: •加载所有配置信息得到Conf ...

  7. JavaWeb学习(三十)———— 数据库连接池

    一.应用程序直接获取数据库连接的缺点 用户每次请求都需要向数据库获得链接,而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长.假设网站一天10万访问量,数据库服务器就需要创建10万次连接,极大 ...

  8. Tomcat 与 数据库连接池 的小坑

    连接池的优点众所周知. 我们可以自己实现数据库连接池,也可引入实现数据库连接池的jar包,按要求进行配置后直接使用. 关于这方面的资料,好多dalao博客上记录的都是旧版本Tomcat的配置方式,很可 ...

  9. javaweb基础(39)_数据库连接池

    一.应用程序直接获取数据库连接的缺点 用户每次请求都需要向数据库获得链接,而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长.假设网站一天10万访问量,数据库服务器就需要创建10万次连接,极大 ...

  10. Java学习:数据库连接池技术

    本节内容 数据库连接池 Spring JDBC : JDBC Template 数据库连接池 1.概念:其实就是一个容器(集合),存放数据库连接的容器 当系统初始化好后,容器中会申请一些连接对象,当用 ...

随机推荐

  1. 6_SSM

    一. ssm整合 1.1 项目创建 1.1.1 创建Maven项目 创建一个普通的Maven-web项目,名称为ssm 记得勾选上Create from archetype然后选择后缀为maven-a ...

  2. 【前端必会】不知道webpack插件? webpack插件源码分析BannerPlugin

    背景 不知道webpack插件是怎么回事,除了官方的文档外,还有一个很直观的方式,就是看源码. 看源码是一个挖宝的行动,也是一次冒险,我们可以找一些代码量不是很大的源码 比如webpack插件,我们就 ...

  3. 如何理解「数字化是 IT 公司在给传统企业贩卖焦虑」?

    焦虑,不是IT公司贩卖给传统企业的!这个论断本身就不成立!数字化的动因是企业内部,生产中的七大浪费还不够么?数据不畅导致的决策失败还少吗?去问下企业业主,诸如此类的问题多了去了,数字化服务商只是来帮着 ...

  4. spring boot集成redis基础入门

    redis 支持持久化数据,不仅支持key-value类型的数据,还拥有list,set,zset,hash等数据结构的存储. 可以进行master-slave模式的数据备份 更多redis相关文档请 ...

  5. Docker | 部署nginx服务

    容器时相互隔离的,docker启动的nginx是容器内的服务,不影响我原先服务器上的nginx服务,小伙伴们可大胆尝试 本篇实在linux环境下操作的,主要目的是夺人眼目,对使用Docker部署服务尝 ...

  6. P2216 [HAOI2007]理想的正方形 方法记录

    [HAOI2007]理想的正方形 题目描述 有一个 \(a \times b\) 的整数组成的矩阵,现请你从中找出一个 \(n \times n\) 的正方形区域,使得该区域所有数中的最大值和最小值的 ...

  7. virtualbox的Linux虚拟磁盘大小调整及注意事项

    virtualBox 调整磁盘分区 起因 起初安装centos6.3 时,没有修改默认的硬盘空间.只有8G,导致后面安装完zookeeper,jdk之后,在安装mysql发现磁盘空间不足 扩容步骤 1 ...

  8. vulnhub靶场|NAPPING: 1.0.1

    准备: 攻击机:虚拟机kali.本机win10. 靶机:NAPPING: 1.0.1,地址我这里设置的桥接,,下载地址:https://download.vulnhub.com/napping/nap ...

  9. 20220728 - DP训练 #1

    20220728 - DP训练 #1 时间记录 \(8:00-9:00\) T1 尝试做 \(T1\),可惜并未做出,没有想到是资源分配 设置三维状态,初值一直不知道怎么设置 并且对于距离有一部分不会 ...

  10. centos7 安装RabbitMQ3.6.15 以及各种报错

    成功图镇楼 各个版本之间的差异不大,安装前要确保rabbitmq 的版本和 elang的版本一致.预防各种错乱. 注意点:(重要!!重要!!) * 同时安装的时候最好确保rabbitmq和erlang ...