咱們有了sqlalchemy後,依然不能像django同樣愉快的實現python manage.py makemigration/ migrate。對於數據庫表結構的改變,sqlalchemy的限制是比較嚴格的。其實sqlalchemy的做者爲咱們提供瞭解決方案alembic(邏輯相似於git),而flask-migrate經過flask-script模塊對alembic進行了進一步的封裝。爲了實現migrate,天然須要先了解script和alembic兩個模塊
Flask-Script主要實現的功能是經過命令行的形式來操做Flask。例如python manage.py func1 -u argspython
一般flask-script的manage.py文件爲flask文件的入口mysql
from flask_script import Manager from flaskapp import app,DatabaseTable,db manager = Manager(app) # 經過command裝飾器實現無參數命令,python manage.py greet @manager.command def greet(): print('你好') # 經過option裝飾器實現帶參數命令python manage.py -u lala -e la@l.com # -u表明第一個參數的簡稱,--username是全稱, dest 是參數傳遞的目標形參 @manager.option("-u","--username",dest="username") @manager.option("-e","--email",dest="email") def add_user(username,email): user = DatabaseTable(username=username,email=email) db.session.add(user) db.session.commit()
# manage.py from flask_script import Manager from db_script import db_manager manager = Manager(app) manager.add_command("db",db_manager) # 註冊子命令,db爲自命令的名稱 # db_script.py from flask_script import Manager db_manager = Manager() @db_manager.command def init(): print('遷移倉庫建立完畢!') @db_manager.command def revision(): print('遷移腳本生成成功!') @db_manager.command def upgrade(): print('腳本映射到數據庫成功!') # 調用python manage.py db init
用來更改數據庫結構git
具體遷移步驟:sql
1. 定義好本身的模型
2. 使用alembic建立一個倉庫:`alembic init [倉庫的名字,推薦使用alembic]`。 模塊會建立指定名字的文件夾
3. 修改配置文件:
* 在`alembic.ini`中,給`sqlalchemy.url`設置數據庫的鏈接方式。這個鏈接方式跟sqlalchemy的方式同樣的。
* 在`alembic/env.py`中的`target_metadata`設置模型的`Base.metadata`,要導入`models`。可以使用相對路徑:
```python
import sys,os
sys.path.append(os.path.dirname(os.path.dirname(__file__))) # 若是是flask-sqlalchemy用db.Model.metabase
```
4. 將ORM模型生成遷移腳本:`alembic revision --autogenerate -m '想要加的消息'`。 # -m 是消息 。 會根據表結構的更改而自動生成腳本
5. 將生成的腳本映射到數據庫中:`alembic upgrade head`。 這一步才更改數據庫,head能夠是腳本編碼,在腳本文件中能找到腳本編碼
6. 之後若是修改了模型,重複四、5步驟。數據庫
1. init:建立一個alembic倉庫。 2. revision:建立一個新的版本文件。 用這個生成了一個腳本。而後用upgrade改 3. --autogenerate:自動將當前模型的修改,生成遷移腳本。 4. -m:本次遷移作了哪些修改,用戶能夠指定這個參數,方便回顧。 5. upgrade:將指定版本的遷移文件映射到數據庫中,會執行版本文件中的upgrade函數。若是有多個遷移腳本沒有被映射到數據庫中,那麼會執行多個遷移腳本。upgrade加版本號就能夠了,head指向最新的版本 6. [head]:表明最新的遷移腳本的版本號。 7. downgrade:會執行指定版本的遷移文件中的downgrade函數。 8. heads:展現head指向的腳本文件版本號。 9. history:列出全部的遷移版本及其信息。 10. current:展現當前數據庫中的版本號。
flask-migrate對alembic的命令經過flask-script進行了封裝django
from flask_script import Manager from zhiliao import app from exts import db from flask_migrate import Migrate,MigrateCommand manager = Manager(app) # 綁定app和db到flask_migrate Migrate(app,db) # 添加Migrate的全部子命令到db子命令下 manager.add_command("db",MigrateCommand) if __name__ == '__main__': manager.run()
1. 初始化一個環境:python manage.py db init 2. 自動檢測模型,生成遷移腳本:python manage.py db migrate 3. 將遷移腳本映射到數據庫中:python manage.py db upgrade 4. 更多命令:python manage.py db --help
結合sqlalchemy簡單實例flask
from flask import Flask import config from exts import db app = Flask(__name__) app.config.from_object(config) db.init_app(app) @app.route('/') def hello_world(): return 'Hello World!' @app.route("/profile/") def profile(): pass if __name__ == '__main__': app.run()
DB_USERNAME = 'root' DB_PASSWORD = 'root' DB_HOST = '127.0.0.1' DB_PORT = '3306' DB_NAME = 'flask_migrate_demo' DB_URI = 'mysql+pymysql://%s:%s@%s:%s/%s?charset=utf8' % (DB_USERNAME,DB_PASSWORD,DB_HOST,DB_PORT,DB_NAME) SQLALCHEMY_DATABASE_URI = DB_URI
# 該文件的目的是爲了防止model.py和flaskapp的循環引用 from flask_sqlalchemy import SQLAlchemy db = SQLAlchemy()
from exts import db class User(db.Model): __tablename__ = 'user' id = db.Column(db.Integer,primary_key=True,autoincrement=True) username = db.Column(db.String(50),nullable=False) age = db.Column(db.Integer)
from flask_script import Manager from flaskapp import app from exts import db from flask_migrate import Migrate,MigrateCommand from models import User # 這裏必定要導入 manager = Manager(app) Migrate(app,db) manager.add_command("db",MigrateCommand) if __name__ == '__main__': manager.run()