1.flask-migratehtml
2.flask-sessionpython
3.蓝图:Blueprintmysql
4.蓝图的运行机制redis
sql
更好的解决办法是使用数据库迁移框架,它能够追踪数据库模式的变化,而后把变更应用到数据库中。数据库
在Flask中可使用Flask-Migrate扩展,来实现数据迁移。而且集成到Flask-Script中,全部操做经过命令就能完成。django
为了导出数据库迁移命令,Flask-Migrate提供了一个MigrateCommand类,能够附加到flask-script的manager对象上。json
pip install flask-migrate
from flask import Flask from config import Config from flask_sqlalchemy import SQLAlchemy from flask_migrate import Migrate,MigrateCommand # 1.引入Migrate和MigrateCommand from flask_script import Manager,Command app = Flask(__name__,template_folder='templates') app.config.from_object(Config) manage = Manager(app) db = SQLAlchemy(app) # 2.建立migrate对象。第一个参数是Flask的实例,第二个参数是Sqlalchemy数据库实例 migrate = Migrate(app,db) # 3.manager是Flask-Script的实例,这条语句在flask-Script中添加一个db命令 manage.add_command('db',MigrateCommand) achieve = db.Table('tb_achievement', db.Column('student_id', db.Integer, db.ForeignKey('tb_student.id')), db.Column('course_id', db.Integer, db.ForeignKey('tb_course.id')) ) class Course(db.Model): __tablename__ = 'tb_course' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(64), unique=True) price = db.Column(db.Numeric(6,2)) teacher_id = db.Column(db.Integer, db.ForeignKey('tb_teacher.id')) students = db.relationship('Student', secondary=achieve, backref='courses', lazy='subquery') def __repr__(self): return 'Course:%s'% self.name class Student(db.Model): __tablename__ = 'tb_student' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(64), unique=True) email = db.Column(db.String(64),unique=True) age = db.Column(db.SmallInteger,nullable=False) sex = db.Column(db.Boolean,default=1) def __repr__(self): return 'Student:%s' % self.name class Teacher(db.Model): __tablename__ = 'tb_teacher' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(64), unique=True) courses = db.relationship('Course', backref='teacher', lazy='subquery') def __repr__(self): return 'Teacher:%s' % self.name @app.route("/") def index(): return "ok" if __name__ == '__main__': manage.run()
1.建立迁移版本仓库flask
# 这个命令会建立migrations文件夹,全部迁移文件都放在里面。 python main.py db init
2.建立迁移版本仓库浏览器
# 这里等同于django里面的 makemigrations,生成迁移版本文件 python main.py db migrate -m 'initial migration'
3.升级迁移版本库的版本
python main.py db upgrade
4.降级迁移版本库的版本
python main.py db downgrade
5.回滚到指定版本
python manage.py db downgrade 版本号 # 返回到指定版本号对应的版本
6.查看数据库迁移历史(可查看数据库迁移版本号)
python manage.py db history # 输出格式:<base> -> 版本号 (head), initial migration
通常数据迁移的步骤是:init-->migrate-->upgrade/downgrade
flask-session:容许设置session到指定存储的空间中
pip install flask-Session
使用session以前,必须配置一下配置项:
SECRET_KEY = "*(%#4sxcz(^(#$#8423" # session秘钥
from flask import Flask,session from flask_redis import FlaskRedis from flask_session import Session app = Flask(__name__) redis = FlaskRedis() session_store = Session() class Config(): # DEBUG调试模式 DEBUG = True # json多字节转unicode编码 JSON_AS_ASCII = False # 数据库连接配置 SECRET_KEY = "*(%#4sxcz(^(#$#8423" # 1.session存储方式为redis SESSION_TYPE = "redis" # 2.session保存数据到redis时启用的连接对象 SESSION_REDIS = redis # 3.若是设置session的生命周期是不是会话期, 为True,则关闭浏览器session就失效 SESSION_PERMANENT = True # 4.是否对发送到浏览器上session的cookie值进行加密 SESSION_USE_SIGNER = True # 5.保存到redis的session数的名称前缀 SESSION_KEY_PREFIX = "session:" # 6.redis的连接配置 REDIS_URL = "redis://localhost:6379/1" app.config.from_object(Config) # 将Config类注册到app上 redis.init_app(app) # 将flask-redis对象挂载到app上 session_store.init_app(app) # 将flask-session对象挂载到app上 @app.route("/") def index(): session["username"] = "xiaoming" return "Ok" @app.route("/get_session") def get_session(): print( session["username"] ) return "ok" @app.route("/redis1") def set_redis(): # redis给集合数据类型/哈希数据类型设置值 redis.set("username","xiaohuihui") redis.hset("brother","zhangfei","17") return "ok" @app.route("/redis2") def get_redis(): user = redis.get("username").decode() brother = redis.hgetall("brother") print(brother["zhangfei".encode()].decode()) return "ok" if __name__ == '__main__': app.run()
from flask import Flask,session from flask_redis import FlaskRedis from flask_session import Session from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) db = SQLAlchemy() redis = FlaskRedis() session_store = Session() class Config(): ...... '''数据库连接配置''' # SQLALCHEMY_DATABASE_URI = "mysql://帐号:密码@IP/数据库名?编码" SQLALCHEMY_DATABASE_URI = "mysql://root:123@127.0.0.1:3306/students?charset=utf8mb4" # 动态追踪修改设置,如未设置只会提示警告 SQLALCHEMY_TRACK_MODIFICATIONS = True # 查询时会显示原始SQL语句 SQLALCHEMY_ECHO = True '''数据库保存session''' SESSION_TYPE = 'sqlalchemy' # session类型为sqlalchemy SESSION_SQLALCHEMY = db # SQLAlchemy对象 SESSION_SQLALCHEMY_TABLE = 'tb_session' # session要保存的表名称 SESSION_PERMANENT = True # 若是设置为True,则关闭浏览器session就失效。 SESSION_USE_SIGNER = False # 是否对发送到浏览器上session的cookie值进行加密 SESSION_KEY_PREFIX = 'session:' # 保存到session中的值的前缀 db.init_app(app) app.config.from_object(Config) redis.init_app(app) session_store.init_app(app) @app.route("/") def index(): session["username"] = "xiaohui" return "Ok" @app.route("/get_session") def get_session(): return session["username"] if __name__ == '__main__': # with app.app_context(): # db.create_all() app.run()
简单来讲,Blueprint 是一个存储视图方法的容器,这些操做在这个Blueprint 被注册到一个应用以后就能够被调用,Flask 能够经过Blueprint来组织URL以及处理请求。
Flask使用Blueprint让应用实现模块化,在Flask中,Blueprint具备以下属性:
一个项目能够具备多个Blueprint
能够将一个Blueprint注册到任何一个未使用的URL下好比 “/”、“/sample”或者子域名
在一个应用中,一个模块能够注册屡次
Blueprint能够单独具备本身的模板、静态文件或者其它的通用操做方法,它并非必需要实现应用的视图和函数的
在一个应用初始化时,就应该要注册须要使用的Blueprint
可是一个Blueprint并非一个完整的应用,它不能独立于应用运行,而必需要注册到某一个应用中。
Blueprint对象用起来和一个应用/Flask对象差很少,最大的区别在于一个 蓝图对象没有办法独立运行,必须将它注册到一个应用对象上才能生效.
1.
from flask import Blueprint # 1. 建立蓝图目录并对蓝图对象进行初始化 users_blue = Blueprint("users",__name__,template_folder="users_templates",static_folder='users_static',static_url_path="/libs")
2.在这个蓝图目录下, 建立views.py文件,保存当前蓝图使用的视图函数
from . import users_blue from flask import render_template # 2. 编写视图 @users_blue.route("/") def index(): return render_template("index.html",title="users/index/index.html") @users_blue.route("/list") def list(): return "users/list"
3.
# 3. 注册视图 from .views import *
4.
# 4. 注册蓝图 from users import users_blue app.register_blueprint(users_blue,url_prefix="/users")
当这个应用启动后,经过/users/能够访问到蓝图中定义的视图函数
当咱们在应用对象上注册一个蓝图时,能够指定一个url_prefix关键字参数(这个参数默认是/)
url_for在使用时,若是要生成一个蓝图里面的视图对应的路由地址,则须要声明当前蓝图名称+视图名称
url_for('users.home') # /users/home
下面的示例将蓝图所在目录下的static_users目录设置为静态目录
from flask import Blueprint # 经过static_folder参数设置静态文件目录 users_blue = Blueprint("users",__name__,static_folder='users_static')
定制静态目录URL规则 :能够在建立蓝图对象时使用 static_url_path 来改变静态目录的路由。
下面的示例将为 users/static 文件夹的路由设置为 /lib
from flask import Blueprint # 经过static_url_path设置静态文件路由 users_blue = Blueprint("users",__name__,static_folder='users_static',static_url_path='/lib')
访问http://127.0.0.1:5000/users/libs/1.jpg 便可查看到图片
蓝图对象默认的模板目录为系统的模版目录,能够在建立蓝图对象时使用 template_folder 关键字参数设置模板目录
users_blue = Blueprint("users",__name__,static_folder='users_static',static_url_path='/libs',template_folder='users_templates')
注意:若是在 templates 中存在和 templates_users 有同名模板文件时, 则系统会优先使用 templates 中的文件
蓝图是保存了一组未来能够在应用对象上执行的操做,注册路由就是一种操做
当在app对象上调用 route 装饰器注册路由时,这个操做将修改对象的url_map路由表
然而,蓝图对象根本没有路由表,当咱们在蓝图对象上调用route装饰器注册路由时,它只是在内部的一个延迟操做记录列表defered_functions中添加了一个项
当执行app对象的 register_blueprint() 方法时,应用对象将从蓝图对象的 defered_functions 列表中取出每一项,并以自身做为参数执行该匿名函数,即调用应用对象的 add_url_rule() 方法,这将真正的修改应用对象的usr_map路由表