Flask從入門到精通之使用Flask-Migrate實現數據庫遷移

  在開發程序的過程當中,你會發現有時須要修改數據庫模型,並且修改以後還須要更新數據庫。僅當數據庫表不存在時,Flask-SQLAlchemy 纔會根據模型進行建立。所以,更新表的惟一方式就是先刪除舊錶,不過這樣作會丟失數據庫中的全部數據。更新表的更好方法是使用數據庫遷移框架。源碼版本控制工具能夠跟蹤源碼文件的變化,相似地,數據庫遷移框架能跟蹤數據庫模式的變化,而後增量式的把變化應用到數據庫中。html

  SQLAlchemy 的主力開發人員編寫了一個遷移框架,稱爲Alembic(https://alembic.readthedocs.org/en/latest/index.html)。除了直接使用Alembic 以外,Flask 程序還可以使用Flask-Migrate(http://flask-migrate.readthedocs.org/en/latest/)擴展。這個擴展對Alembic 作了輕量級包裝,並集成到Flask-Script 中,全部操做都經過Flask-Script 命令完成。python

一.建立遷移倉庫數據庫

  首先,咱們要在虛擬環境中安裝Flask-Migrate:flask

pip install flask-migrate

  這個擴展的初始化方法以下所示:app

from flask.ext.migrate import Migrate, MigrateCommand
migrate = Migrate(app, db)
manager.add_command('db', MigrateCommand)

  爲了導出數據庫遷移命令,Flask-Migrate 提供了一個MigrateCommand 類,可附加到Flask-Script 的manager 對象上。在這個例子中,MigrateCommand 類使用db 命令附加。框架

  在維護數據庫遷移以前,要使用init 子命令建立遷移倉庫:函數

python hello.py db init
Creating directory /home/flask/flask1/migrations ... done
  Creating directory /home/flask/flask1/migrations/versions ... done
  Generating /home/flask/flask1/migrations/env.pyc ... done
  Generating /home/flask/flask1/migrations/alembic.ini ... done
  Generating /home/flask/flask1/migrations/README ... done
  Generating /home/flask/flask1/migrations/script.py.mako ... done
  Generating /home/flask/flask1/migrations/env.py ... done
  Please edit configuration/connection/logging settings in
  '/home/flask/flask1/migrations/alembic.ini' before proceeding.

  這個命令會建立migrations 文件夾,全部遷移腳本都存放其中。數據庫遷移倉庫中的文件要和程序的其餘文件一塊兒歸入版本控制。工具

二.建立遷移腳本spa

  在Alembic 中,數據庫遷移用遷移腳本表示。腳本中有兩個函數,分別是upgrade() 和downgrade()。upgrade() 函數把遷移中的改動應用到數據庫中,downgrade() 函數則將改動刪除。Alembic 具備添加和刪除改動的能力,所以數據庫可重設到修改歷史的任意一點。版本控制

  咱們可使用revision 命令手動建立Alembic 遷移,也可以使用migrate 命令自動建立。手動建立的遷移只是一個骨架,upgrade() 和downgrade() 函數都是空的,開發者要使用Alembic 提供的Operations 對象指令實現具體操做。自動建立的遷移會根據模型定義和數據庫當前狀態之間的差別生成upgrade() 和downgrade() 函數的內容。自動建立的遷移不必定老是正確的,有可能會漏掉一些細節。自動生成遷移腳本後必定要進行檢查。

  migrate 子命令用來自動建立遷移腳本:

 python hello.py db migrate -m "initial migration"
INFO  [alembic.runtime.migration] Context impl MySQLImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
INFO  [alembic.autogenerate.compare] Detected removed table u'sys_user'
INFO  [alembic.autogenerate.compare] Detected removed table u'sys_role_privilege'
INFO  [alembic.autogenerate.compare] Detected removed table u'sys_role'
INFO  [alembic.autogenerate.compare] Detected removed table u'sys_privilege'
INFO  [alembic.autogenerate.compare] Detected removed table u'sys_dict'
INFO  [alembic.autogenerate.compare] Detected removed table u'user info'
INFO  [alembic.autogenerate.compare] Detected removed table u'country'
INFO  [alembic.autogenerate.compare] Detected removed table u'sys_user_role'
  Generating
  /home/flask/flask1/migrations/versions/f52784fdd592_initial_migration.py ... done

三.更新數據庫

  檢查並修正好遷移腳本以後,咱們可使用db upgrade 命令把遷移應用到數據庫中:

python hello.py db upgrade
INFO  [alembic.runtime.migration] Context impl MySQLImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
INFO  [alembic.runtime.migration] Running upgrade  -> f52784fdd592, initial migration

  對第一個遷移來講, 其做用和調用db.create_all() 方法同樣。但在後續的遷移中,upgrade 命令能把改動應用到數據庫中,且不影響其中保存的數據。

相關文章
相關標籤/搜索