Flask 创建命令数据库迁移flask-migrate

数据库迁移

  • 在开发过程中,需要修改数据库模型,而且还要在修改之后更新数据库。最直接的方式就是删除旧表,但这样会丢失数据。
  • 更好的解决办法是使用数据库迁移框架,它可以追踪数据库模式的变化,然后把变动应用到数据库中。
  • 在Flask中可以使用Flask-Migrate扩展,来实现数据迁移。并且集成到Flask-Script中,所有操作通过命令就能完成。
  • 为了导出数据库迁移命令,Flask-Migrate提供了一个MigrateCommand类,可以附加到flask-script的manager对象上。

首先要在虚拟环境中安装Flask-Migrate。

pip install flask-migrate

代码文件内容:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_script import Manager
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate, MigrateCommand
app = Flask(__name__)

class Config():
    # DEBUG调试模式
    DEBUG = True
    # json多字节转unicode编码
    JSON_AS_ASCII = False
    # 数据库链接配置
    # SQLALCHEMY_DATABASE_URI = "mysql://账号:密码@IP/数据库名?编码"
    SQLALCHEMY_DATABASE_URI = "mysql://root:[email protected]:3306/student?charset=utf8mb4"
    # 动态追踪修改设置,如未设置只会提示警告
    SQLALCHEMY_TRACK_MODIFICATIONS = True
    # 查询时会显示原始SQL语句
    SQLALCHEMY_ECHO = True

app.config.from_object(Config)


# 初始化Manager  两个意思是一样的
#manager = Manager(app)
manager.app = app


# 初始化SQLAlchemy
db = SQLAlchemy()
db.init_app(app)


# 数据迁移
# 第一个参数是Flask的实例,第二个参数是Sqlalchemy数据库实例
migrate = Migrate(app,db)
# manager是Flask-Script的实例,这条语句在flask-Script中添加一个db命令
manager.add_command('db', MigrateCommand)


"""创建模型类"""
# db.Table(
# 表名,
# db.Column("字段名",字段类型,外键声明),
# db.Column("字段名",字段类型,外键声明),
# )
"""以db.Table关系表来确定模型之间的多对多关联"""
achievement = 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')),

    # 这里的表信息,在主键模型中,仅仅表达的是关联关系,所以中间表的字段,无法通过主模型来获取
    db.Column("created_time",db.DateTime,comment="考试时间"),
    db.Column("score",db.DECIMAL(5,2),comment="成绩")
)


class Student(db.Model):
    __tablename__ = "tb_student"
    id = db.Column(db.Integer, primary_key=True,comment="主键ID")
    name = db.Column(db.String(250), comment="姓名")
    age = db.Column(db.Integer, comment="年龄")
    sex = db.Column(db.Boolean, default=False, comment="性别")
    money = db.Column(db.DECIMAL(8,2), nullable=True, comment="钱包")
    # 关联属性,是SQLAlchemy提供给开发者快速引用外键模型的一个对象属性,不存在于mySQL中!!!
    # backref 反向引用,类似django的related,通过外键模型查询主模型数据时的关联属性
    info = db.relationship("StudentInfo", backref="own", uselist=False)
    #course_list = db.relationship("Course", secondary=achievement,backref="student_list",lazy="dynamic")
    def __repr__(self):
        return self.name

class StudentInfo(db.Model):
    __tablename__ = "tb_student_info"
    id = db.Column(db.Integer, primary_key=True, comment="主键ID")
    sid= db.Column(db.Integer,db.ForeignKey(Student.id), comment="学生")
    address = db.Column(db.String(255), nullable=True, comment="家庭住址")
    mobile = db.Column(db.String(15), unique=True, comment="紧急联系电话")

    def __repr__(self):
        return self.own.name

class Teacher(db.Model):
    __tablename__ = "tb_teacher"
    id = db.Column(db.Integer, primary_key=True, comment="主键ID")
    name = db.Column(db.String(250), comment="姓名")
    # sex = db.Column(db.Boolean, default=False, comment="性别")
    option = db.Column(db.Enum("老师","助教","班主任"), default="老师", comment="教职")
    course_list = db.relationship("Course",uselist=True, backref="teacher",lazy="subquery")
    def __repr__(self):
        return self.name

class Course(db.Model):
    __tablename__ = "tb_course"
    id = db.Column(db.Integer, primary_key=True, comment="主键ID")
    name = db.Column(db.String(250), unique=True, comment="课程名称")
    price = db.Column(db.Numeric(6, 2))
    teacher_id = db.Column(db.Integer,db.ForeignKey(Teacher.id),comment='老师')
    student_list = db.relationship('Student', secondary=achievement,backref='course_list',lazy='dynamic')

    def __repr__(self):
        return self.name

@app.route("/")
def index():
 
    return "Ok"


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


创建迁移版本仓库

这个命令会创建migrations文件夹,所有迁移文件都放在里面。


python main.py db init
创建迁移版本
  • 自动创建迁移版本有两个函数
    • upgrade():函数把迁移中的改动应用到数据库中。
    • downgrade():函数则将改动删除。
  • 自动创建的迁移脚本会根据模型定义和数据库当前状态的差异,生成upgrade()和downgrade()函数的内容。
  • 对比不一定完全正确,有可能会遗漏一些细节,需要进行检查
python main.py db migrate -m 'initial migration'

# 这里等同于django里面的 makemigrations,生成迁移版本文件
升级版本库的版本
python main.py db upgrade 
降级版本库的版本
python main.py db downgrade
版本库的历史管理

可以根据history命令找到版本号,然后传给downgrade命令:

python manage.py db history
​输出格式:<base> ->  版本号 (head), initial migration

回滚到指定版本

python manage.py db downgrade # 默认返回上一个版本
python manage.py db downgrade 版本号   # 返回到指定版本号对应的版本

数据迁移的步骤:

1. 初始化数据迁移的目录
python manage.py db init

2. 数据库的数据迁移版本初始化
python manage.py db migrate -m 'initial migration'

3. 升级版本[创建表/创建字段/修改字段]
python manage.py db upgrade 

4. 降级版本[删除表/删除字段/恢复字段]
python manage.py db downgrade
模块推荐

文档: https://faker.readthedocs.io/en/master/locales/zh_CN.html

批量生成测试数据: https://github.com/joke2k/faker

你可能感兴趣的:(flask,python,flask)