前言:
- 使用數據庫遷移,可以直接建表,而不用我們自己寫sql語句用來建表。就是將關系型數據庫的一張張表轉化成了Python的一個個類。
- 在開發中經常會遇到需要修改原來的數據庫模型,修改之后更新數據庫,最簡單粗暴的方式就是刪除舊表,然后在增加新表,這樣做的缺點是會造成數據丟失。
- 使用數據庫遷移,可以追蹤數據庫模式的變化,然后把變動應用到數據庫中。
- 在flask中使用Flask-Migrate來實現數據庫遷移,並且集成到Flask-Script中,所有的操作通過命令來完成。
- 為了導出數據庫遷移命令,Flask-Migrate使用了一個MigrateCommand類,可以附加到Flask-Script的manager對象上。
安裝Flask-Migrate
pip install flask-migrate
Python代碼,用戶類和角色類。
#!/usr/bin/python #coding:utf-8 from flask import Flask from flask_sqlalchemy import SQLAlchemy from flask_script import Manager from flask_migrate import Migrate,MigrateCommand """ flask_migrate作用: 1、通過命令的方式創建表 2、修改表的結構 """ class Config(object): SQLALCHEMY_DATABASE_URI = "mysql://root:@127.0.0.1:3306/book" # 這個值可以設置,也可以不設置,如果不設置,那么會一直報警告 SQLALCHEMY_TRACK_MODIFICATIONS = False # 這里有個坑,下次再講。在lask-sqlalchemy 2.0之后就不在需要設置這一項了。 SQLALCHEMY_COMMIT_ON_TEARDOWN = True app = Flask(__name__) app.config.from_object(Config) db = SQLAlchemy(app) manager = Manager(app) # 第一個參數是flask實例,第二個參數SQLAlchemy實例 Migrate(app, db) #manager是Flask-Script的實例,這條語句在flask-Script中添加一個db命令 manager.add_command("db", MigrateCommand) class Role(db.Model): __tablename__ = "roles" id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(128)) title = db.Column(db.String(128)) us = db.relationship("User",backref="role") class User(db.Model): __tablename__="users" id = db.Column(db.Integer,primary_key=True) name = db.Column(db.String(128)) email = db.Column(db.String(128)) password = db.Column(db.String(128)) role_id = db.Column(db.Integer,db.ForeignKey("roles.id")) @app.route("/") def index(): return "index" if __name__ == '__main__': manager.run()
關於config的配置,可以參考flask-Script中文文檔
遷移數據庫三步走:
第一步:創建遷移倉庫
python database.py db init
這里的db是遷移命令的對象,名字可以隨便取,但是需要保持一致。
這個命令會創建migrations文件夾,所有遷移文件都放在里面。
這里只是創建了遷移倉庫,表還沒創建。
可以看到表還沒有創建。
第二步:創建遷移腳本
- 自動創建遷移腳本有兩個函數
- upgrade():函數把遷移中的改動應用到數據庫中。
- downgrade():函數則將改動刪除。
- 自動創建的遷移腳本會根據模型定義和數據庫當前狀態的差異,生成upgrade()和downgrade()函數的內容。
- 對比不一定完全正確,有可能會遺漏一些細節,需要進行檢查
python database.py db migrate -m 'initial migration'
"initial migration"是注釋
在windows下這里也存在一個坑。
這個坑在這里解釋下:
windows系統不支持cmd接收的參數中含有空格,例如我們上面'initial migration',系統收到的是兩個參數,所以報錯會顯示參數過多。
我的解決辦法是在兩個單詞之間加上“_”連接當然方法很多,我這里就使用這種簡單粗暴的。
這種情況下,注釋會報錯。
這樣則不會。
運行命令之后,只是在migrations文件夾中新增了數據庫遷移的版本文件並沒有在數據庫也只是創建了版本號,並沒有生成對應的表。
第三步:更新數據庫
更新數據庫命令:
python migrate.py db upgrade
可以看到已經創建表成功了。
如果我們需要講roles表中的title字段刪除,我們再看下版本文件的變化。
刪除前:
刪除后:
將代碼中的title刪除,然后再次執行遷移腳本命令
python migrate.py db migrate -m 'del_title'
這個時候數據庫中title字段還沒有被刪除
執行更新數據庫操作:
可以看到數據庫中,數據被刪除。
python migrate.py db upgrade
實際操作順序: 1.python 文件 db init 2.python 文件 db migrate -m"版本名(注釋)" 3.python 文件 db upgrade 然后觀察表結構 4.根據需求修改模型 5.python 文件 db migrate -m"新版本名(注釋)" 6.python 文件 db upgrade 然后觀察表結構 7.若返回版本,則利用 python 文件 db history查看版本號 8.python 文件 db downgrade(upgrade) 版本號
先寫這么多,發現寫起來,真的有很多內容可以寫。待續。。。