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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM