欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Flask09——数据库迁移

程序员文章站 2022-07-13 08:46:55
...

我们在开发软件的时候往往会有这样的情况,数据库里面的表不是一下子全部键好的,往往是随着开发功能的增加,会不断的增加新表,新的字段,而我们之前也讲了清空表的语句drop_all,创建表的语句creat_all,我们好像可以通过这两个语句对表进行更改,添加新的字段,新的表。
但是,大家有没有想过一个问题,我们每次要添加新的字段的时候都要将表数据全部清空,这就意味着我们要删除之前的数据,再重新建立表结构,再重新插入新的数据,当然如果是在我们的开发测试阶段,这种操作姑且还是可以接受的,而当我们的产品正式上线运行了,我们又不得不加入新的字段呢?这个时候清空表?恐怕是不能被接受的吧。
所以我们就需要有一个工具来帮我们在不影响原有表结构和数据的情况下,增加字段到表当中,或者增加新表。而这个工具就是我们的数据库迁移工具migrate。这个工具集中包含了大量可以通过命令行来操作表的指令。让我们可以很轻松的添加新的表,新的字段。
而在我们介绍这个迁移工具之前,我们先需要了解另外一个库:flask_script库,这个库首先帮我们实现了让我们可以在命令行调用pytho文件中写的函数,实现了这个功能之后我们就可以用同样的方式在命令行当中去操作表了,而我们的迁移工具的指令实际上也是通过python文件中的函数来实现的。所以就相当于flask_script帮我们完成了命令行操作文件中函数的事情,而flask_migrate中就集合了大量的可以操作数据库的指令。两者完美的结合,就使得我们可以通过命令行操作数据库了。
好让我们先来了解怎么通过flask_script实现命令行运行python中函数的。
首先通过命令 pip install flask-script
新建文件 script1.py 输入以下代码,代码注释如下:

from flask import Flask
from flask_script import Manager  # 引入脚本命令行类


app = Flask(__name__)

manager = Manager(app=app)  # 实例化脚本命令行类,并传递app


@manager.command  # 通过装饰器将普通函数变成可以通过命令行运行的函数
def cmd_hello():
    print('命令行打印hello')


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

然后,在命令行找到此文件所在位置,输入命令python script1.py cmd_hello 并运行。如果你能看到命令行输出:命令行打印hello 代表已经成功通过命令行运行了函数cmd_hello了。

上面我们已经实现了通过命令行运行函数的功能,我们还可以将一个函数集,比如将操作数据库的命令放到一个文件当中,然后再将命令添加到manager当中,并增加前缀,这样我们就可以实现通过命令行调用一个文件当中所有函数的功能了。代码如下:

# 文件script2
from flask import Flask
from flask_script import Manager
from cmd_db import dbManager


app = Flask(__name__)

manager = Manager(app=app)

manager.add_command('db', dbManager)  #


@manager.command
def cmd_hello():
    print('命令行打印hello')


if __name__ == '__main__':
    manager.run()
# 与script2.py同级目录下文件cmd_db.py文件
from flask_script import Manager

dbManager = Manager()  # 不是作为主文件运行,所以不用传入app


@dbManager.command
def connect_mysql():
    print('连接mysql数据库')


@dbManager.command
def select_one():
    print(('查询单个'))

这样我们就可以通过命令:python script2.py db connect_mysqlpython script2.py db select_one来执行上面两个函数了。
结合上面例子的思想,我们也可以用同样的道理将迁移命令引入进来。代码如下:

# apps.py文件
"""Todo 将实例化app和绑定插件到app上的操作单独放在一个文件当中"""
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)

app.config.from_object('setting')

db = SQLAlchemy(app=app)
# setting.py文件
DEBUG = True
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:@127.0.0.1:3306/test1?charset=utf8'
SQLALCHEMY_ECHO = True
SQLALCHEMY_TRACK_MODIFICATIONS = False
SECRET_KEY = '123'
# models.py
from apps import  *


class Article(db.Model):
    id = db.Column(db.Integer, primary_key=True, comment='主键ID')
    title = db.Column(db.String(30), nullable=False, comment='文章标题')
# script3.py文件
from apps import *

from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand  # 引入迁移库和迁移命令集
from models import *  # 引入模型


manager = Manager(app=app)  # 实例化命令行类

migrate = Migrate(app=app, db=db)  # 实例化迁移类

manager.add_command('db', MigrateCommand)  # 将迁移命令添加到可以通过命令行执行的命令中,并加前缀db

if __name__ == '__main__':
    manager.run()  # 运行命令行脚本

然后再命令行依次执行如下三个命令:
①、python script3.py db init 初始化迁移文件,执行之后,会生成迁移文件夹,记录初始化的版本。
②、python script3.py db migrate 生成与models文件当中定义的模型的迁移文件,记录了数据库的表、字段信息等。
③、python script3.py db upgrade 将迁移文件映射到数据库生成数据库的表

如果以上三个命令执行之后,成功在数据库创建了article表,并且包含两个字段id和title的话,就说明创建表成功。
修改models文件。

# models.py文件
class Article(db.Model):
    id = db.Column(db.Integer, primary_key=True, comment='主键ID')
    title = db.Column(db.String(30), nullable=False, comment='文章标题')
    content = db.Column(db.Text, comment='文章内容')

重复执行
python script3.py db migratepython script3.py db upgrade 命令,如果看到content字段被增加成功,那就说明数据库迁移成功。