1. 程式人生 > 實用技巧 >Flask flask-migrate 資料庫遷移

Flask flask-migrate 資料庫遷移

簡介

flask-migrate是flask的一個擴充套件模組,主要是擴充套件資料庫表結構的.

官方文件:http://flask-migrate.readthedocs.io/en/latest/

使用

使用一共分為三步:

建立遷移環境->生成遷移指令碼->更新資料庫

本地資料庫連線與相關配置檔案 config.py

import os
​
​
DEBUG = True
# DEBUG = False
SECRET_KEY = os.urandom(24)
​
# HOSTNAME = 'mysql'
HOSTNAME = '127.0.0.1'
PORT = '3306'
DATABASE = 'autumnwater'
USERNAME = 'root'
PASSWORD = 'root'
​
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8'.format(USERNAME, PASSWORD, HOSTNAME, PORT,
                                                                               DATABASE)
​
SQLALCHEMY_TRACK_MODIFICATIONS = False

資料庫遷移檔案 manage.py

from flask_script import Manager
from flask_migrate import MigrateCommand, Migrate
from index import app
from exts import db
​
#    存放命令指令碼
​
manager = Manager(app)
​
# 使用Migrate繫結app和db
migrate = Migrate(app, db)
​
# 新增遷移指令碼的命令到manager中
manager.add_command('db', MigrateCommand)
​
if __name__ == '__main__':
    manager.run()

如果沒有下載flask-migrate會報錯,使用pip下載,下載後可檢視已安裝庫檔案:

執行命令

python manage.py db init   
#初始化資料庫,會建立一個migations資料夾,並且會在資料庫中生成一個alembic_version表
python manage.py db migrate  
#建立遷移歷史(遷移指令碼)
python manage.py db upgrade  
#更新資料庫

注:只有在第一次遷移的時候需要初始化資料庫

具體步驟如下:

  1. 在MySQL中建立資料庫,此處我們的資料庫名為:autumnwater

  2. 使用命令

    python manage.py db init

    初始化資料庫,會建立一個migations資料夾,該資料夾是Alembic模組自動建立的,預設名字叫migrations,可以在建立migrate=Migrate(app,db)物件時傳入directory="filename"引數來自定義目錄名

    migrations 裡面有一個versions資料夾,這個資料夾用來存放遷移指令碼,執行遷移命令後會自動生成遷移指令碼儲存在裡面

    同時會在資料庫中生成一個alembic_version表

    我這裡是python3的環境,所以上述命令 python -> python3

    同時可見migations資料夾已生成:

  3. 使用命令

    python manage.py db migrate

    建立遷移歷史(遷移指令碼),可以通過 -m 引數新增遷移資訊,類似於git提交程式碼時新增提交資訊,例如:

    python manage.py db migrate -m "create table"

    執行該步驟時顯示

    解決方案尋找:

    https://blog.csdn.net/qq_41389354/article/details/104254677

    直接使用pip install pymysql即可

    又出現新的錯誤

    擷取部分報錯為:

    sqlalchemy.exc.ProgrammingError: (pymysql.err.ProgrammingError) (1146, "Table 'performance_schema.session_variables' doesn't exist") [SQL: SHOW VARIABLES LIKE 'sql_mode'] (Background on this error at: http://sqlalche.me/e/13/f405)

    在 stackoverflow 上找到解決方案:

    https://stackoverflow.com/questions/31967527/table-performance-schema-session-variables-doesnt-exist

    進入mysql的bin目錄下,開啟cmd執行:

    mysql_upgrade -u root -p --force

    出現該問題的原因應該是之前我將phpstudy裡面的mysql強制升級為了5.7版本

    重啟phpstudy,然後重新執行

    python manage.py db migrate

    如圖:

  4. 最後更新資料庫,完成遷移

    python manage.py db upgrade

    檢視資料庫的表

    如圖,執行 upgrade 命令後,會在資料庫中建立一張 alembic_version 表,這張表不是程式碼中定義的,是 Alembic 自動建立的(看名字就知道了),裡面儲存的是當前資料庫的版本 id

    alembic_version 表不能刪除,刪除後就不能繼續執行資料庫遷移操作了,除非重新初始化。

    同時,執行 upgrade 命令後,會根據程式碼中定義的模型類建立對應的表,表的欄位與模型類中定義的一致。

    如上面的資料庫中建立了user表,因為在我的models裡面定義了該表:

    from exts import db
    from datetime import datetime
    from werkzeug.security import generate_password_hash, check_password_hash
    ​
    ​
    class User(db.Model):
        __tablename__ = 'user'
        id = db.Column(db.Integer, primary_key=True, autoincrement=True)
        email = db.Column(db.String(20), nullable=False)
        username = db.Column(db.String(50), nullable=False)
        pw_hash = db.Column(db.String(128), nullable=False)
    ​
        def __init__(self, email, username, password):
            self.email = email
            self.username = username
            self.set_password(password)
    ​
        def set_password(self, password):
            self.pw_hash = generate_password_hash(password)
    ​
        def check_password(self, password):
            return check_password_hash(self.pw_hash, password)

    而如果資料庫中有其他表(沒有對應模型類的表),會被刪除。這點需要特別注意,資料庫遷移時最好使用一個新的資料庫(不要與其他專案用同一個資料庫),避免造成資料丟失。

優勢

個人直觀感受使用資料庫遷移的優勢有:

  • 使用資料庫遷移,可以直接建表,而不用我們自己寫sql語句用來建表。就是將關係型資料庫的一張張錶轉化成了Python的一個個類。

    這裡即我們之前在 models.py 檔案中建立的類,可以通過資料庫遷移直接生成表

  • 在開發中經常會遇到需要修改原來的資料庫模型,修改之後更新資料庫,最簡單粗暴的方式就是刪除舊錶,然後在增加新表,這樣做的缺點是會造成資料丟失。在 Flask 中,可以使用資料庫遷移來解決這個問題,資料庫遷移可以追蹤資料模型類的變化,然後把變動應用到資料庫中,不會刪表造成資料丟失。

大部分參考COPY

https://www.cnblogs.com/jiangchunsheng/p/9218338.html

https://blog.csdn.net/weixin_43790276/article/details/103554632

https://www.jianshu.com/p/70cc32d9d2ff