Flask脚本(flask-script/flask-migrate)、数据库迁移出现的问题

一、flask-script用法

flask官方提供了一个扩展组件flask-script可以实现在shell下操作我们的Flask项目。

安装flask-script

pip install flask-script

1.flask-script简单实现

server.py

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello World!'

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

manage.py

from flask_script import Manager
from server import app

manager = Manager(app)

@manager.command
def hello():
    print('hello world')

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

解读:manage.py

1.从flask_script模块中导入flask_script的核心类Manager

from flask_script import Manager 

2.从server.py模块中把app对象导入

from server import app

3.从Manager()类传入app对象实例化出manager对象,manager对象用于后面所有添加命令

manager = Manager(app)

4.利用@manager.command装饰器添加以被装饰函数的名字命名的一条命令被装饰函数的映射

@manager.command   # 相当于添加了一条hello命令,可以调用到hello函数
def hello():
    print('hello world')

5.manager调用run方法之前定义的命令才会生效

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

在shell中切入到该manage.py的目录中,并且进入虚拟环境。输入命令python manage.py hello

>>python manage.py hello     

命令中的hello是@manager.command装饰器装饰的函数名,执行命令后会调用hello函数

2.命令添加方式   (在manage.py文件中写)

第一种(无参命令): 使用manager.command方式添加命令

...
@manager.command
def demo():
    print('无参命令')
...

执行命令:

>>python manage.py demo

第二种(有参命令): 使用manager.option('-简单的命令','--全写的命令',dest='传给函数的参数')添加命令

...
@manager.option("-u","--username",dest="username")
@manager.option("-p","--password",dest="password")
def login(username, password):
    print("用户名:{}  密码: {}".format(username,password))
...

执行命令:

>>python manage.py login -u mark -p 123

第三种(子命令):

比如一个功能对应着很多个命令,这个时候就可以用子命令来实现,可以将这些命令的映射单独放到一个文件方便管理。在这个放着很多命令映射的文件中实例化Manager类出一个新的对象,并在manage.py文件中通过以下命令来添加子命令

manager.add_command("子命令",Manager对象)

db_script.py文件  (命令映射文件)

from flask_script import Manager

db_Manager = Manager()

@db_Manager.command
def init():
    print('初始迁移仓库')

@db_Manager.command
def migrate():
    print('生成迁移脚本')

@db_Manager.command
def upgrade():
    print("迁移脚本映射到数据库")

manage.py

from flask_script import Manager
from server import app
from db_script import db_Manager # 导入子命令文件的Manager类实例化出的对象
manager = Manager(app)

manager.add_command("db",db_Manager) # 添加子命令

切入到manage.py所在的目录中,执行以下命令

>> python manage.py db init
>> python manage.py db migrate
>> python manage.py db upgrade

二、使用Flask-Migrate迁移数据库

pip install flask-migrate

为了导出数据库迁移命令,Flask-Migrate提供了一个MigrateCommand类,可附加到Flask-Script的manager对象上。在这个例子中,MigrateCommand类使用db命令附加

我们的Flask_Migrate的操作是在shell下完成的,所以要基于Flask-script,Flask-Migrate提供了一个MigrateCommand类,需要附加到Flask-Script的manager对象上,完成命令的创建,
并且Flask_Migrate同时体统了Migrate类,需要加载核心对象app和数据库对象db。完成迁移工具的配置。

1.配置Flask_Migrate

manage.py

from flask_script import Manager
from flask_migrate import Migrate,MigrateCommand
from exts import db
from server import app
manager = Manager(app)

Migrate(app,db)

manager.add_command('db',MigrateCommand)

解读:manage.py

1.首先从flask_migrate中导入Migrate,MigrateCommand

from flask_migrate import Migrate,MigrateCommand

2.Migrate加载app对象和db对象获取数据库的配置信息以及模型表信息

Migrate(app,db)

3.把MigrateCommand附加到manager创建迁移数据库的子命令

manager.add_command('db',MigrateCommand)   #db是迁移命令的对象,名字可以随便取

2.迁移脚本命令

1.创建迁移仓库

>> python manage.py db init

这个命令会创建migrations文件夹,所有迁移文件都放在里面。这里只是创建了迁移仓库,表还没创建

2.创建迁移脚本

>> python manage.py db migrate -m '注释信息'    #注释信息可写可不写

该命令会在数据库创建一张 alembic_version 表,存放着数据库迁移脚本的版本信息,该命令会搜集到需要迁移的模型表信息,写入到脚本中,但是并没有真正的映射到数据库中。

3.更新数据库

>> python manage.py db upgrade

如果对models.py进行修改,需要重新执行

 

python  manage.py  db  migrate  -m  "新版本注释"
python  manage.py  db  upgrade 

三、数据库迁移期间出现的问题 

1.执行 python manage.py db init 可以正常生成文件夹migrations

2.运行 python manage.py db migrate 无法生成建表文件,migrations文件夹下的versions为空,同时控制台报一个警告,这个并不是无法生成建表文件的原因

Warning: (1366, "Incorrect string value: '\\xD6\\xD0\\xB9\\xFA\\x
B1\\xEA...' for column 'VARIABLE_VALUE' at row 484")

无法生成建表文件是因为:

原来flask-migrate是检测上下文中db.Model的子类来创建表的,所有我们必须让这个app能够知道有这个models文件的存在,所以,在app的文件夹里的__init__文件夹中加上,
因为我们在manage.py中导入app中的文件时,会自动导入__init__.py文件夹,或者在manage.py中导入也行 在__init__.py 或者manage.py 中导入models里面的所有类
from App.models import * 具体导入看自己写的模块路径

这一句,就可以顺利生成建表文件及表结构文件。注意:如果之前有migrate文件夹,需要先将migrate文件夹删除

python manage.py db migrate -m 'data_test'

 

 

python manage.py db upgrade

 

posted @ 2020-06-15 23:42  只会玩辅助  阅读(1613)  评论(0编辑  收藏  举报