Flask的插件sessionSQLAlchemyScriptMigrate

Posted tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flask的插件sessionSQLAlchemyScriptMigrate相关的知识,希望对你有一定的参考价值。

一、flask-session

1、为什么要使用flask-session

因为flask默认的session是通过请求上下文放入到Local中的,是存在内存的,
而使用flask-session可以更改session存放的位置,
可以存放在redis、memcached、filesystem、mongodb、sqlalchemy等数据库中,
flask-session也是基于flask原本的session原理实现的,只是让session存放的位置更改了而已。

 

实现原理:
-- 内置的session调用 session_interface = xxxxx
  -- xxxxx.open_session 解密cookie转换成字典给session
  -- xxxxx.save_session 将session加密给cookie
-- Flask-session通过修改session_interface指定的类
  -- 来改变session存储的位置

 

2、使用步骤

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)

 

3、Demo(使用蓝图搭建的Demo)

# 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
__init__.py
# 2. settings.py
import redis


class DevConfig(object):
    DEBUG = True
    SESSION_TYPE = \'redis\'
    SESSION_REDIS = redis.Redis(host=\'localhost\', port=6379)
2. settings.py
# 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"
3. user.py

 

二、Flask-SQLAlchemy

1、前戏

学习Flask-SQLAlchemy之前,我们先去学习一下SQLAlchemy(可看上一篇),SQLAlchemy是一个Python的ORM框架,SQLAlchemy
而Flask-SQLAlchemy是基于SQLAlchemy实现的一个Flask插件。

 

2、使用步骤

1. 下载 pip install flask-sqlalchemy

 

2. 导入 from flask_sqlalchemy import SQLAlchemy

 

3. 在init.py 实例化 并且实现初始化

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. 建models

# 表必须继承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. 生成表

# 需要使用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操作

跟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
__init__.py
# 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
settings.py
# 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\'))
models.py
# 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()
run_models.py
# 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"
user.py
# manager.py
from FlaskPlug import create_app


app = create_app()

if __name__ == \'__main__\':

    app.run()
manager.py

 

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  # 获取总页数

 

三、Flask-Script

1、下载安装

pip install flask-script

 

2、使用

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

 

3、自定义命令

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()

 

四、Flask-Migrate

1、下载

pip install flask-migrate

 

2、注意

flask-migrate依赖flask-script

 

3、使用

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()

 

以上是关于Flask的插件sessionSQLAlchemyScriptMigrate的主要内容,如果未能解决你的问题,请参考以下文章

Flask之Flask_Session插件

Flask 插件学习:Flask-WTF 和 WTForms 扩展

基于whoosh的flask全文搜索插件flask-msearch

Flask数据库插件安装与配置教程

Flask数据库插件安装与配置教程

Flask数据库插件安装与配置教程