由於flask默認的session是經過請求上下文放入到Local中的,是存在內存的,
而使用flask-session能夠更改session存放的位置,
能夠存放在redis、memcached、filesystem、mongodb、sqlalchemy等數據庫中,
flask-session也是基於flask本來的session原理實現的,只是讓session存放的位置更改了而已。html
實現原理:
-- 內置的session調用 session_interface = xxxxx
-- xxxxx.open_session 解密cookie轉換成字典給session
-- xxxxx.save_session 將session加密給cookie
-- Flask-session經過修改session_interface指定的類
-- 來改變session存儲的位置python
1. 下載 pip install flask-session 2. 導入 from flask-session import Session 到__init__的app實例裏面 3. 更改配置文件 class DevConfig(object): DEBUG = True SESSION_TYPE = "redis" SESSION_REDIS = redis.Redis(host="127.0.0.1", port="6379") 4. 實例化 Session(app)
# 1. __init__.py from flask import Flask from FlaskPlug.views.user import userBlue # 測試的視圖 from flask_session import Session # 導入插件flask-session def create_app(): app = Flask(__name__, template_folder='templates') # 更改配置信息 app.config.from_object('settings.DevConfig') # 實例化 Session(app) app.register_blueprint(userBlue) return app
# 2. settings.py import redis class DevConfig(object): DEBUG = True SESSION_TYPE = 'redis' SESSION_REDIS = redis.Redis(host='localhost', port=6379)
# 3. user.py from flask import Blueprint, session userBlue = Blueprint("userBlue", __name__) @userBlue.route('/') def index(): session['test'] = 'test-flask-session' return "index" @userBlue.route("/user") def user(): print(session.get('test')) return "user"
學習Flask-SQLAlchemy以前,咱們先去學習一下SQLAlchemy(可看上一篇),SQLAlchemy是一個Python的ORM框架,SQLAlchemy
而Flask-SQLAlchemy是基於SQLAlchemy實現的一個Flask插件。mysql
1. 下載 pip install flask-sqlalchemyredis
2. 導入 from flask_sqlalchemy import SQLAlchemysql
3. 在init.py 實例化 而且實現初始化mongodb
from flask import Flask from flask_sqlalchemy import SQLAlchemy # SQLAlchemy必須在導入藍圖以前實例化 db = SQLAlchemy() from FlaskPlug.views.user import userBlue def create_app(): app = Flask(__name__) # 導入配置信息 app.config.from_object('settings.DevConfig') app.register_blueprint(userBlue) # 初始化db db.init_app(app) return app
4. 配置文件數據庫
# settings.py class DevConfig(object): DEBUG = True # flask-SQLAlchemy配置 # 鏈接什麼數據庫,哪一個數據庫 SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:123abc@127.0.0.1:3306/sqlalchemy?charset=utf8' SQLALCHEMY_POOL_SIZE = 5 SQLALCHEMY_MAX_OVERFLOW = 2 SQLALCHEMY_TRACK_MODIFICATIONS = False
5. 建modelsflask
# 表必須繼承flask-SQLAlchemy的SQLAlchemy的實例化對象db.Model from FlaskPlug import db # 其餘一些字段的東西導入的是python的SQLAlchemy # 固然,也可使用db.Column, db.Integer, db.String, db.relationship等等 from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index from sqlalchemy.orm import relationship class Book(db.Model): __tablename__ = 'book' id = Column(Integer, primary_key=True) title = Column(String(64), nullable=False) publisher_id = Column(Integer, ForeignKey('publisher.id')) publisher = relationship('Publisher', backref='books') tags = relationship('Tag', backref='books', secondary='book2tag') __table_args__ = ( # UniqueConstraint聯合惟一,這個聯合惟一的字段名爲:uni_id_name UniqueConstraint("id", "title", name="uni_id_title"), # 聯合索引 Index("id", "title") ) def __repr__(self): return self.title class Publisher(db.Model): __tablename__ = 'publisher' id = Column(Integer, primary_key=True) title = Column(String(64), nullable=False) def __repr__(self): return self.title class Tag(db.Model): __tablename__ = 'tag' id = Column(Integer, primary_key=True) title = Column(String(64), nullable=False) def __repr__(self): return self.title class Book2Tag(db.Model): __tablename__ = 'book2tag' id = Column(Integer, primary_key=True) book_id = Column(Integer, ForeignKey('book.id')) tag_id = Column(Integer, ForeignKey('tag.id'))
6. 生成表cookie
# 須要使用app上下文 # 離線腳本這時候就體現做用了 from FlaskPlug import db, create_app # 必定要導入models 不然找不到表建立不出來 from FlaskPlug.models import * app = create_app() # app_context()就是前兩篇文章裏面Flask請求上下文走過的流程啊 # app_ctx = AppContext(app) app_ctx = app.app_context() # with 就會去走AppContext的__enter__和__exit__方法 # __enter__就是去取app了,__exit__就是刪除 with app_ctx: db.create_all() 注意:通常建表的py文件和生成表的py文件要分紅兩個文件執行,否則有時候會致使循環引用。
7. 基於flask-SQLAlchemy的ORM操做session
跟python的SQLAlchemy同樣的 @userBlue.route('/') def index(): # 給Tag增長一條數據 tag_obj = Tag(title='python') db.session.add(tag_obj) db.session.commit() db.session.close() return "index"
8. Demo
# __init__.py from flask import Flask from flask_sqlalchemy import SQLAlchemy db = SQLAlchemy() from FlaskPlug.views.user import userBlue def create_app(): app = Flask(__name__, template_folder='templates') app.config.from_object('settings.DevConfig') app.register_blueprint(userBlue) db.init_app(app) return app
# settings.py class DevConfig(object): DEBUG = True # flask-SQLAlchemy配置 SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:123abc@127.0.0.1:3306/sqlalchemy?charset=utf8' SQLALCHEMY_POOL_SIZE = 5 SQLALCHEMY_MAX_OVERFLOW = 2 SQLALCHEMY_TRACK_MODIFICATIONS = False
# models.py from FlaskPlug import db from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index from sqlalchemy.orm import relationship class Book(db.Model): __tablename__ = 'book' id = Column(Integer, primary_key=True) title = Column(String(64), nullable=False) publisher_id = Column(Integer, ForeignKey('publisher.id')) publisher = relationship('Publisher', backref='books') tags = relationship('Tag', backref='books', secondary='book2tag') __table_args__ = ( # UniqueConstraint聯合惟一,這個聯合惟一的字段名爲:uni_id_name UniqueConstraint("id", "title", name="uni_id_title"), # 聯合索引 Index("id", "title") ) def __repr__(self): return self.title class Publisher(db.Model): __tablename__ = 'publisher' id = Column(Integer, primary_key=True) title = Column(String(64), nullable=False) def __repr__(self): return self.title class Tag(db.Model): __tablename__ = 'tag' id = Column(Integer, primary_key=True) title = Column(String(64), nullable=False) def __repr__(self): return self.title class Book2Tag(db.Model): __tablename__ = 'book2tag' id = Column(Integer, primary_key=True) book_id = Column(Integer, ForeignKey('book.id')) tag_id = Column(Integer, ForeignKey('tag.id'))
# run_models.py from FlaskPlug import db, create_app # 必定要導入models 不然找不到表建立不出來 from FlaskPlug.models import * app = create_app() # app_context()就是前兩篇文章裏面Flask請求上下文走過的流程啊 # app_ctx = AppContext(app) app_ctx = app.app_context() # with 就會去走AppContext的__enter__和__exit__方法 # __enter__就是去取app了,__exit__就是刪除 with app_ctx: db.create_all()
# user.py from flask import Blueprint, session from FlaskPlug import db from FlaskPlug.models import Tag, Book, Publisher userBlue = Blueprint("userBlue", __name__) @userBlue.route('/') def index(): # 給Tag增長一條數據 tag_obj = Tag(title='python') db.session.add(tag_obj) db.session.commit() db.session.close() return "index"
# manager.py from FlaskPlug import create_app app = create_app() if __name__ == '__main__': app.run()
9.注意
flask-sqlalchemy跟sqlalchemy的語法是如出一轍的,只是flask-sqlalchemy的session是從flask-sqlalchemy的SQLALchemy實例化對象中拿到。
可是值得注意的還有一點,flask-sqlalchemy除了徹底支持sqlalchemy的語法外,它也有本身的查詢語法,例如:
""" 使用的是上面例子中的表 """ # flask-sqlalchemy查詢語法:類名.query.查詢操做 ret = Tag.query.get(1) # python ret2 = Tag.query.filter_by(id=1).first() # python ret3 = Tag.query.filter(Tag.id==1).first() # python # sqlalchemy查詢語法:db.session.query(類名).查詢操做 ret4 = db.session.query(Tag).get(1) # python ret5 = db.session.query(Tag).filter_by(id=1).first() # python ret6 = db.session.query(Tag).filter(Tag.id==1).first() # python """ 更多示例 假設User是咱們建的一個表 """ # 查詢全部用戶數據 User.query.all() # 查詢有多少個用戶 User.query.count() # 查詢第1個用戶 User.query.first() User.query.get(1) # 根據id查詢 # 查詢id爲4的用戶[3種方式] User.query.get(4) User.query.filter_by(id=4).all() # 簡單查詢 使用關鍵字實參的形式來設置字段名 User.query.filter(User.id == 4).all() # 複雜查詢 使用恆等式等其餘形式來設置條件 # 查詢名字結尾字符爲g的全部用戶[開始 / 包含] User.query.filter(User.name.endswith("g")).all() User.query.filter(User.name.startswith("w")).all() User.query.filter(User.name.contains("n")).all() User.query.filter(User.name.like("%n%g")).all() # 模糊查詢 # 查詢名字和郵箱都以li開頭的全部用戶[2種方式] User.query.filter(User.name.startswith("li"), User.email.startswith("li")).all() from sqlalchemy import and_ User.query.filter(and_(User.name.startswith("li"), User.email.startswith("li"))).all() # 查詢age是25 或者 `email`以`itheima.com`結尾的全部用戶 from sqlalchemy import or_ User.query.filter(or_(User.age == 25, User.email.endswith("itheima.com"))).all() # 查詢名字不等於wang的全部用戶[2種方式] from sqlalchemy import not_ User.query.filter(not_(User.name == "wang")).all() User.query.filter(User.name != "wang").all() # 查詢id爲[1, 3, 5, 7, 9]的用戶 User.query.filter(User.id.in_([1, 3, 5, 7, 9])).all() # 全部用戶先按年齡從小到大, 再按id從大到小排序, 取前5個 User.query.order_by(User.age, User.id.desc()).limit(5).all() # 分頁查詢, 每頁3個, 查詢第2頁的數據 pn = User.query.paginate(2, 3) pn.items # 獲取該頁的數據 pn.page # 獲取當前的頁碼 pn.pages # 獲取總頁數
pip install flask-script
1. manager.py下的代碼 from FlaskPlug import create_app from flask_script import Manager app = create_app() manager = Manager(app) if __name__ == '__main__': # app.run() manager.run() 2. 啓動命令 這樣使用Manager後,咱們就能夠在Terminal中啓動咱們的項目 或者在cmd裏面 cd到項目目錄下啓動也能夠 啓動命令變成 1. 使用默認端口 python manager.py runserver 2. 自定義域名和端口 python manager.py runserver -h 127.0.0.1 -p 8000
from FlaskPlug import create_app from flask_script import Manager, Command app = create_app() manager = Manager(app) # 方法一 class Hello(Command): """ 繼承Command,並重寫run方法 自定義命令 python manager.py hello_girl """ def run(self): print('hello world') # 添加命令和對應的對象 manager.add_command('hello_girl', Hello()) # 方法二 # 位置傳參 @manager.command def my_add(arg1, arg2): """ 使用裝飾器command 自定義命令 python manager.py my_add 1 2 """ ret = int(arg1) + int(arg2) print(arg1, arg2, ret) # 方法三 # 關鍵字傳參 # 關鍵字參數的簡寫:-n # 關鍵字參數全寫:--name # 關鍵字的描述:dest @manager.option('-n', '--name', dest='name') @manager.option('-a', '--age', dest='age') def person(name, age): """ 使用裝飾器option 自定義命令 執行: python manager.py person -n 小明 --age 28 """ print(name, age) if __name__ == '__main__': # app.run() manager.run()
pip install flask-migrate
flask-migrate依賴flask-script
from FlaskPlug import create_app, db from FlaskPlug.models import * from flask_script import Manager from flask_migrate import Migrate, MigrateCommand # 1. 導入SQLAlchemy的實例化db和script、migrate插件 app = create_app() manager = Manager(app) Migrate(app, db) # 2. 實例化Migrate # 3. 給manager添加命令(MigrateCommand裏面就存放了自定義的命令) manager.add_command("db", MigrateCommand) """ 數據庫遷移命令 依賴 flask-script python manager.py db init # 初始化 python manager.py db migrate # 至關於Django的ORM的makemigrations python manager.py db upgrade # 至關於Django的ORM的migrate """ if __name__ == '__main__': # app.run() manager.run()