数据库迁移
首先要在虚拟环境中安装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
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