zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    vimrc之fileformat
    std::copy ( myvector.begin(), myvector.end(), out_it )
    backtrace、backtrace_symbols
    mysql之replicate_do_table/replicate_ingore_table/replicate_wide_do_table/replicate_wide_ingore_table
    symbol lookup error
    mysql之select into outfile
    flex与bison
    运行maven打出来的jar包报错:Unable to locate Spring NamespaceHandler for XML schema namespace
    让maven生成可运行jar包
    windows下通过Git Bash使用Git常用命令
  • 原文地址:https://www.cnblogs.com/wangcuican/p/13138583.html
Copyright © 2011-2022 走看看