一、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

