flask_sqlalchemy以及flask_script还有 flask_migrate

 

flask _script

这里是功能扩展,有sqlalchemy_script插件,可以帮我们自定制命令,使用script的时候就不用在app.run了,去到terminal里面输入指令python manage.py runserver 就能把程序启动起来,就像我们的django一样,

这里的script就是把我们的runserver的指令改成我们自定义的,下图所示,它使用场景是自定义运行脚本

 

这里有梗概点进来

有更详细的博客介绍戳这里

 

 

 

我们的flask_script需要基于蓝图来实现

 

代码在这里:

这里是views视图里面的py文件

from flask import blueprints
xxx=blueprints.Blueprint('xxx',__name__)
@xxx.route('/index',methods=['GET','POST'])
def index():
    return 'in me the tiger'

 

下面是manage.py文件也就是启动文件

from sqlalchemy_script import create_app
from flask_script import Manager

aps=create_app()
manag=Manager(aps)
@manag.command
def costo(obj):
    print(obj)

if __name__ == '__main__':
    manag.run()

 

init文件

from flask import Flask
from .views.accou import xxx
def create_app():
    app = Flask(__name__)
    app.register_blueprint(xxx)
    return app

 

 

我们把flask和sqlalchemy数据库结合起来使用

 

按照老师笔记里面的步骤一步一步来做

先把蓝图的目录结构给创建出来,

1,在init文件里面创建db对象

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

# 包含了跟sqlalchemy相关的所有操作
db = SQLAlchemy()


def create_aps():
    aps = Flask(__name__)
    aps.config.from_object('settings.DevelopmentConfig')
    from .views.account import ac  # 这里是把我们的蓝图导入

    aps.register_blueprint(ac)  # 然后通过蓝图去注册app
    db.init_app(aps)  # 2.在init里面把我们的app给传入到db中去
    return aps

 

3.写配置文件,在settings文件中写好配置项

class BaseConfig():
    SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:123@127.0.0.1:3306/book_list?charset=utf8'
    SQLALCHEMY_POOL_SIZE = 5
    SQLALCHEMY_POOL_TIMEOUT = 30
    SQLALCHEMY_POOL_RECYCLE = -1
    # 追踪对象的修改并且发送信号
    SQLALCHEMY_TRACK_MODIFICATIONS = False


class ProductionConfig(BaseConfig):
    ...


class DevelopmentConfig(BaseConfig):
    ...


class TestingConfig(BaseConfig):
    ...

 

 

4.在model里面把表格给定义好

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
from sqlalchemy_flask import db
from sqlalchemy import create_engine

# Base = declarative_base()


class Actors(db.Model):
    __tablename__ = 'actors'
    id = Column(Integer, primary_key=True, autoincrement=True)
    name = Column(String(32), nullable=True, unique=True)


class Name(db.Model):
    __tablename__ = 'name'
    id = Column(Integer, primary_key=True, autoincrement=True)
    cname = Column(String(32), nullable=True, unique=True)

 

5.创建数据库表,我们用离线脚本实现这个功能,

"""
web运行时,flask程序运行起来,
用户通过浏览器访问离线脚本,自定义的一个py文件+使用flask中定义好的功能
这里的主要功能就是帮我们的程序来创建或者是删除model表,我们如果不用这个离线脚本的话就用我们之前写好的model里面的代码一样可以达到效果,
就是把类创建好,然后把drop和init方法都定义好,执行当前py文件来创建或者是删除表格,
我们在这里用离线脚本就是为了节省代码,我们想用flask里面的内置方法去实现我们的功能,就需要在这里用离线脚本把源码里面封装的方法给调用上
"""
from sqlalchemy_flask import db
from sqlalchemy_flask import create_aps
# from sqlalchemy_flask import model

app = create_aps()
with app.app_context():
    # db.drop_all()
    db.create_all()  # 这里是离线脚本在运行,我们的model里面的写的code_first都是继承了db.Model里面封装的方法,所以我们在这里调用
    # db里面的create_all()或者是drop_all()方法都是在我们的db里面封装好的,所以我们在这里执行db.create_all()方法就会把
    # 我们的model里面的code_first类都用orm给创建好数据库中的表了,他们之间的关联是在这里建立的,
    # 用我们的db这个sqlalchemy类实例化出来的对象来建立的

    # ret = db.session.query(model.Actors).all()
    # print(ret)

 

6,在视图中使用sqlalchemy操作数据库

from flask import blueprints
from sqlalchemy_flask import model
from sqlalchemy_flask import db


ac = blueprints.Blueprint('ac', __name__)


@ac.route('/login', methods=['GET', 'POST'])
def login():
    data = db.session.query(model.Actors).all()
    obj=db.session.query(model.Name).all()
    print(data,obj)
    db.session.remove()
    return 'hello from other world'

 

最后在manage里面

from sqlalchemy_flask import create_aps
from flask_script import Manager

qqx = create_aps()
manager = Manager(qqx)


@manager.command
def custom(arg):
    """
    自定义命令,就是我们在执行runserver的时候可以把这个runserver给替换掉,
    执行我们自己的在这里自定义的命令,这里就是
    python manage.py custom 28 就能启动程序了,custom是我们的函数名,我们函数以什么名字定义这里就是什么指令去执行任务
    :param arg:
    :return:
    """
    print(arg)


@manager.option('-n', '--name', dest='nam')
@manager.option('-u', '--url', dest='url')
def cmd(nam, url):
    """
    自定义命令
    执行:python manage.py cmd -n peter -u http://www.sogo.com
    python manage.py cmd --name wusir  --url http://www.tmall.com
    :param name:
    :param url:
    :return:
    """
    print(nam, url)


if __name__ == '__main__':
    manager.run()

 

 

flask_migrate操作

 

这里代码比较简单,就是我们的manage.py里面的一些简单配置

from flask_migrate import Migrate, MigrateCommand

app = create_app()
manage = Manager(app)
"""
我们在下面使用了flask-migrate组件,就不需要再用我们的离线脚本了,
它就相当于我们django里面的那个makemigration和migrate两个命令,
对于数据库进行监测更新的,
数据库迁移命名
python manage.py db init
python manage.py db migrate # makemigrations
python manage.py db upgrade # migrate
"""
Migrate(app, db)  # 这个Migrate一个它记录一个库的信息,如果需要用到多个库就需要多个与之匹配
manage.add_command('db', MigrateCommand)

其他的就按照正常的逻辑去处理即可,包括文件的目录都不需要改变,不影响这里的参数配置,它只是检测我们的model文件里面的数据库表结构而已,

我们在执行python manage.py db init的时候会自动在数据库里面生成一个文件夹migrations,用来记录我们的数据库中的表的变化,我们用这个命令生成数据库表,在数据库中也会有alembic_version这个表的生成,它记录我们数据中的表的变化

       

 

我们的表每一次变更都需要在migrations文档里面去找version文档里面匹配我们所变更的数据库表里面的version_num数值一致,就能确认是谁发生了变化,然后把变更的结果重新写入到文件里面,达到检测的效果

 

 

 

sqlalchemy建多对多关联表,
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, String, Integer, ForeignKey, Table
from sqlalchemy import create_engine
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy.orm import relationship
Base = declarative_base()


# class Course2Teacher(Base):
#  这里是wusir博客里面的建表方法,有错误,
#     __tablename__ = 'course2teacher'
#
#     id = Column(Integer, primary_key=True, autoincrement=True)
#     course_id = Column(ForeignKey("course_first.id"))
#     teacher_id = Column(ForeignKey("teacher_first.id"))

 """多对多关联的时候是需要手动生成第三张表的"""
teacher_classes = Table( 
  "course2teacher", Base.metadata,
  Column(
"teacher_id", Integer, ForeignKey("teacher_first.id"), nullable=False, primary_key=True),
  Column(
"course_id", Integer, ForeignKey("course_first.id"), nullable=False, primary_key=True)
  )


class Course(Base):
  
__tablename__ = 'course_first'
  id
= Column(Integer, primary_key=True)
  name
= Column(String(32))
  teacher
= relationship("Teacher", secondary="course2teacher", backref='course')


class Teacher(Base):
  __tablename__ = 'teacher_first'
  id
= Column(Integer, primary_key=True, autoincrement=True)
  name
= Column(String(32))


class Student(Base):
  __tablename__ = 'student_first'
  id
= Column(Integer, primary_key=True)
  name
= Column(String(32), index=True, nullable=False)
  course_id
= Column(Integer, ForeignKey("course_first.id"))
  course
= relationship("Course", backref='st_course')

def init_db():
  engine
= create_engine("mysql+pymysql://root:123@127.0.0.1:3306/test?charset=utf8", max_overflow=0, pool_size=5, pool_timeout=30, pool_recycle=-1)
  Base.metadata.create_all(engine)

if __name__ == '__main__':
  init_db()

 

posted @ 2018-05-06 15:31  dream-子皿  阅读(161)  评论(0)    收藏  举报