數(shù)據(jù)庫遷移
在開發(fā)過程中移迫,需要修改數(shù)據(jù)庫模型酬土,而且還要在修改之后更新數(shù)據(jù)庫。最直接的方式就是刪除舊表啃擦,但這樣會丟失數(shù)據(jù)囊蓝。
更好的解決辦法是使用數(shù)據(jù)庫遷移框架,它可以追蹤數(shù)據(jù)庫模式的變化令蛉,然后把變動應(yīng)用到數(shù)據(jù)庫中聚霜。
在Flask中可以使用Flask-Migrate擴(kuò)展,來實(shí)現(xiàn)數(shù)據(jù)遷移珠叔。并且集成到Flask-Script中蝎宇,所有操作通過命令就能完成。
為了導(dǎo)出數(shù)據(jù)庫遷移命令运杭,F(xiàn)lask-Migrate提供了一個MigrateCommand類夫啊,可以附加到flask-script的manager對象上。
首先要在虛擬環(huán)境中安裝Flask-Migrate辆憔。
pip3 install flask-migrate
編寫數(shù)據(jù)庫定義模型類:db_database.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import pymysql
pymysql.install_as_MySQLdb()
from flask_migrate import Migrate,MigrateCommand
from flask_script import Shell,Manager
app = Flask(__name__)
manager = Manager(app)
class Config(object):
"""配置參數(shù)"""
# 設(shè)置連接數(shù)據(jù)庫的URL
user = 'root'
password = '*****************'
database = 'flask_ex'
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://%s:%s@127.0.0.1:3306/%s' % (user,password,database)
# 設(shè)置sqlalchemy自動更跟蹤數(shù)據(jù)庫
SQLALCHEMY_TRACK_MODIFICATIONS = True
# 查詢時會顯示原始SQL語句
# app.config['SQLALCHEMY_ECHO'] = True
# 禁止自動提交數(shù)據(jù)處理
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = False
# 設(shè)置密鑰撇眯,用于csrf_token的加解密
app.config["SECRET_KEY"] = "xhosd6f982yfhowefy29f"
# 讀取配置
app.config.from_object(Config)
# 創(chuàng)建數(shù)據(jù)庫sqlalchemy工具對象
db = SQLAlchemy(app)
#第一個參數(shù)是Flask的實(shí)例,第二個參數(shù)是Sqlalchemy數(shù)據(jù)庫實(shí)例
migrate = Migrate(app,db)
#manager是Flask-Script的實(shí)例虱咧,這條語句在flask-Script中添加一個db命令
manager.add_command('db',MigrateCommand)
#定義模型類-作者
class Author(db.Model):
__tablename__ = 'author'
id = db.Column(db.Integer,primary_key=True)
name = db.Column(db.String(32),unique=True)
email = db.Column(db.String(64))
au_book = db.relationship('Book',backref='author')
def __str__(self):
return 'Author:%s' %self.name
#定義模型類-書名
class Book(db.Model):
__tablename__ = 'books'
id = db.Column(db.Integer,primary_key=True)
info = db.Column(db.String(32),unique=True)
leader = db.Column(db.String(32))
au_book = db.Column(db.Integer,db.ForeignKey('author.id'))
def __str__(self):
return 'Book:%s,%s'%(self.info,self.leader)
if __name__ == '__main__':
# 通過管理對象來啟動flask
manager.run()
創(chuàng)建遷移倉庫
#這個命令會創(chuàng)建migrations文件夾熊榛,所有遷移文件都放在里面。
python3 db_database.py db init
創(chuàng)建遷移腳本
自動創(chuàng)建遷移腳本有兩個函數(shù)腕巡,upgrade()
函數(shù)把遷移中的改動應(yīng)用到數(shù)據(jù)庫中玄坦。downgrade()
函數(shù)則將改動刪除。
自動創(chuàng)建的遷移腳本會根據(jù)模型定義和數(shù)據(jù)庫當(dāng)前狀態(tài)的差異绘沉,生成upgrade()
和downgrade()
函數(shù)的內(nèi)容煎楣。
對比不一定完全正確,有可能會遺漏一些細(xì)節(jié)车伞,需要進(jìn)行檢查
#創(chuàng)建自動遷移腳本
python3 db_database.py db migrate -m "initial migration"
更新數(shù)據(jù)庫
python3 db_database.py db upgrade
回退數(shù)據(jù)庫
回退數(shù)據(jù)庫時择懂,需要指定回退版本號,由于版本號是隨機(jī)字符串另玖,為避免出錯困曙,建議先使用python3 db_database.py db history命令查看歷史版本的具體版本號,然后復(fù)制具體版本號執(zhí)行回退谦去。
python3 db_database.py db downgrade 版本號
執(zhí)行如下: