vlambda博客
学习文章列表

flask_migrate---处理 sqlalchemy 数据迁移的工具

1. 什么是flask_migrate

flask_migrate 是专门用来做sqlalchemy 数据迁移的工具,当据模型发生变化的时可将修改后的模型重新映射到数据库中,这意味着数据库也将被修改。

本文介绍flask_migrate如何在flask项目中使用,所依赖的第三方库和版本信息如下

pip install flask==1.1.4
pip install flask-script==2.0.6
pip install flask_migrate==2.7.0
pip install sqlalchemy==1.4.22

2. 项目结构说明

本文用最小的项目结构来展示flask_migrate如何使用

一共有4个python需要编写,在project目录下有app.pyconfig.pymodels.py, 和project同级目录下需要编写 manager.py

config.py

from pathlib import Path

DATABASE = "migrate.db"
basedir = Path(__file__).resolve().parent
class Config():
SQLALCHEMY_DATABASE_URI = f"sqlite:///{Path(basedir).joinpath(DATABASE)}"
SQLALCHEMY_COMMIT_ON_TEARDOWN = True
SECRET_KEY = 'secret key to protect from csrf'


@staticmethod
def init_app(app):
pass

config.py 是flask项目的配置脚本,为了方便演示,我使用sqlite数据库,SQLALCHEMY_DATABASE_URI是数据的URI配置,sqlalchemy将根据这个配置选择用哪个第三方库作为引擎。

app.py

from flask import Flask
from project.config import Config
from flask_sqlalchemy import SQLAlchemy


app = Flask(__name__)
app.config.from_object(Config)

db = SQLAlchemy()
Config.init_app(app)
db.init_app(app)

from project.models import *

@app.route('/')
def index():
admin = db.session.query(User).filter(User.username =='admin').first()
if admin is None:
return {'status': 0, 'data': {}}
else:
print(admin.name_cn)
return {'status': 1, 'data': {'username': admin.username, 'name_cn': admin.name_cn}}

app.py完成项目的初始化工作,同时提供了一个视图函数index,在index中将会返回管理员的信息。

models.py

from project.app import db
from sqlalchemy import Column, String, Integer
from werkzeug.security import generate_password_hash


class User(db.Model):
__tablename__ = 'user'
id = Column(Integer, primary_key=True, autoincrement=True)
username = Column(String(50), nullable=False)
password = Column(String(80), nullable=False)
name_cn = Column(String(20), nullable=False)

@classmethod
def add_admin(cls):
user = db.session.query(User).filter(User.username =='admin').first()
if user is None:
user = User(username='admin', password=generate_password_hash('123456'), name_cn='管理员')
db.session.add(user)
db.session.commit()

models.py 存放数据库模型,我只定义了一个user表,add_admin方法会向表中添加一个管理员。

manager.py

from flask_script import Manager, Server
from flask_migrate import MigrateCommand, Migrate, upgrade
from project.app import app, db
from project.models import *

manager = Manager(app)
migrate = Migrate(app, db)
# 子命令 MigrateCommand 包含三个方法 init migrate upgrade
manager.add_command('db', MigrateCommand)
manager.add_command('start', Server(host="0.0.0.0", port=8000, use_debugger=True)) # 创建启动命令


@manager.command
def deploy():
upgrade()
User.add_admin()


if __name__ == '__main__':
manager.run()

manager.py 负责管理项目,除了管理数据库,还有server的启动命令start和我自己创建的数据库部署命令deploy。

3. 使用方法

flask_migrate 提供了很多命令,其中最为常用的是init, migrate, upgrade,第一次将数据模型映射到数据库中时,依次执行下面三个命令

python manager.py db init
python manager.py db migrate
python manager.py db upgrade

在这以后,如果数据模型发生了变化,只需要执行migrate 和 upgrade。

执行完上述命令后,此时user表里还没有数据,执行命令

python manager.py deploy

会执行deploy函数,向user表中写入一条管理员数据,在项目初始阶段,个别的表需要预置一些数据,项目才能正常运行,这样做也可以方便测试。

最后执行命令

python manager.py start

会启动flask 服务,在浏览器里访问http://127.0.0.1:8000/ 得到如下响应

{
"data": {
"name_cn": "\u7ba1\u7406\u5458",
"username": "admin"
},
"status": 1
}