flask数据库迁移

1.说明:
当我们在使用flask框架时,写了一个class类,定义了一个实体,我们一般执行如下命令db.create_all()映射到数据库库去,这样最开始没问题,但是当你项目上线时,你会发现你想新增一个字段时,你必须把原有的表给删掉db.drop_all(),再来执行db.create_all()这样才能更新字段,这样会把表里的数据给删掉,这样做不是一个明智的方式, flask给我们提供了两个插件

flask-migrate  // 执行数据表迁移
flask-script  //编写脚本执行数据表迁移, 需要与flask-migrate配合使用

flask-migrate文档
flask-script文档

2.使用

pip install flask-migrate==2.7.0
pip install Flask-Script==2.0.6

3.演示:
flask-migrate用法:


import enum
import pymysql
from flask import Flask, url_for, render_template, request, redirect, make_response
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate, MigrateCommand
# from flask_script import Manager
pymysql.install_as_MySQLdb()

app = Flask(__name__)

# 连接数据库
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:admin@127.0.0.1:3306/flask_db"
# 自动追踪程序的修改 一般不跟踪
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
# 数据库操作自动提交
# app.config["SQLALCHEMY_COMMIT_ON_TEARDOWN"] = True

db = SQLAlchemy(app)


migrate = Migrate(app, db)


class HobbyEnum(enum.Enum):
    BASKETBALL = 1
    BIKE = 2
    CLIMB = 3


class Users(db.Model):
    __tablename__ = "users"
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), nullable=False)
    age = db.Column(db.Integer)
    email = db.Column(db.String(120), unique=True)
    hobby = db.Column(db.Enum(HobbyEnum), default=HobbyEnum.BASKETBALL)

    def __init__(self, username, age, email, hobby):
        self.username = username
        self.age = age
        self.email = email
        self.hobby = hobby

    def __str__(self):
        return '<Users: %s>' % self.username


# 将创建好的实体类映射至数据库
# db.create_all()
# db.drop_all()


if __name__ == '__main__':
    app.run(debug=True)
    

执行如下命令:

flask db init  // 数据表初始化,会在当前项目生成一个migrations文件夹
flask db migrate -m "init db"  // 生成迁移文件,并写上注释
flask db upgrade // 迁移到数据库
flask db downgrade  // 撤销迁移操作, 回退到上一次迁移状态

效果如下:
数据迁移migrateflask-migrate和flask-script配合使用
定义项目结构如下:
项目结构

# settings.py
DATABASE = {
    "USER": "root",
    "PASSWORD": "admin",
    "HOST": "127.0.0.1",
    "PORT": "3306",
    "NAME": "flask_db1"
}

DB_URI = "mysql://{USER}:{PASSWORD}@{HOST}:{PORT}/{NAME}" .format(**DATABASE)
SQLALCHEMY_DATABASE_URI = DB_URI
SQLALCHEMY_TRACK_MODIFICATIONS = False
SQLALCHEMY_COMMIT_ON_TEARDOWN = False
# db_engine.py
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()
# models.py
import enum
from db_engine import db


class HobbyEnum(enum.Enum):
    BASKETBALL = 1
    BIKE = 2
    CLIMB = 3


class Users(db.Model):
    __tablename__ = "users"
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), nullable=False, doc="用户名")
    age = db.Column(db.Integer)
    email = db.Column(db.String(120), unique=True)
    hobby = db.Column(db.Enum(HobbyEnum), default=HobbyEnum.BASKETBALL)

    def __init__(self, username, age, email, hobby):
        self.username = username
        self.age = age
        self.email = email
        self.hobby = hobby

    def __str__(self):
        return '<Users: %s>' % self.username
# app.py
from flask import Flask
import pymysql
from db_engine import db
import settings

pymysql.install_as_MySQLdb()


def create_app():
    app = Flask(__name__)
    app.config.from_object(settings)  # 载入settings.py中的配置信息

    db.init_app(app)  # app绑定数据库db

    return app



if __name__ == '__main__':
    app = create_app()
    app.run(debug=True)

# manage.py
from flask_migrate import Migrate, MigrateCommand
from db_engine import db
from flask_script import Manager, Server
from app import create_app

# 导入要migrate表
import models

app = create_app()  # 实例化一个app对象

manager = Manager(app)  # 实例化一个manager对象

Migrate(app=app, db=db)  # 绑定 数据库与app,建立关系

manager.add_command('db', MigrateCommand)  # 添加迁移命令集到脚本命令

# 如果是以此脚本作为主脚本程序,就执行
if __name__ == '__main__':
    manager.run({"runserver": Server(port=8000, host="0.0.0.0")})

执行命令如下:

python manage.py db init
python manage.py db migrate
python manage.py db upgrade

执行效果同上

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值