flask-mysqldb数据库迁移

数据库迁移

在开发程序的过程中,你会发现有时需要修改数据库模型,而且修改之后还需要更新数据库。仅当数据库表不存在时,Flask-SQLAlchemy 才会根据模型进行创建。因此,更新表的唯一方式就是先删除旧表,不过这样做会丢失数据库中的所有数据。更新表的更好方法是使用数据库迁移框架。源码版本控制工具可以跟踪源码文件的变化,类似地,数据库迁移框架能跟踪数据库模式的变化,然后增量式的把变化应用到数据库中。

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 命令完成。

在虚拟环境中安装Flask-Migrate和flask-script等扩展

pip install flask-migrate
pip install flask-script

创建一个migrate实例,将应用和数据库操作句柄联系在一起

migrate = Migrate(app, db)

在你所创建的xx.py文件中配置以下文件

#flask_script作用是用命令行来管理
from flask_script import Manager
#flask_migrate作用是用来迁移数据库
from flask_migrate import Migrate, MigrateCommand#MigrateCommand迁移指令
from flask_sqlalchemy import SQLAlchemy

# #用于连接数据库的URI                  数据库类型   账号密码    ip     端口   数据库名
app.config['SQLALCHEMY_DATABASE_URI']='mysql://root:mysql@127.0.0.1:3306/flask'
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True#这一步非常耗性能(开启追踪)
app.config['DEBUG'] = True

# 创建一个管理数据库对象(句柄),注意参数需要和app产生联系
db = SQLAlchemy(app)            #SQLAlchemy语言的映射关系
manager = Manager(app, db)
# 第一个参数是Flask-migrate的实例,第二个参数是Sqlalchemy数据库实例,将应用和数据库操作句柄联系在一起
migrate = Migrate(app, db)
# manager是Flask-Script的实例,在其中增加迁移命令,并且起别名db
manager.add_command('db', MigrateCommand)

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

如果执行migrate有报错,信息如下
你需要把你生成的迁移文件的文件夹给删除,再把数据库中的alembic_version表给删除

INFO  [alembic.runtime.migration] Context impl MySQLImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
ERROR [root] Error: Can't locate revision identified by '2b8b9595ef38'

以下操作皆在终端中进行

创建迁移仓库

这个命令会创建migrations文件夹,所有迁移文件都放在里面。

python database.py db init

创建迁移脚本
自动创建迁移脚本有两个函数
upgrade():函数把迁移中的改动应用到数据库中。
downgrade():函数则将改动删除。
自动创建的迁移脚本会根据模型定义和数据库当前状态的差异,生成upgrade()和downgrade()函数的内容。
对比不一定完全正确,有可能会遗漏一些细节,需要进行检查

迁移数据库

python xx.py db migrate -m 'initial migration'

更新数据库

python database.py db upgrade

查看以前的版本

可以根据history命令找到版本号,然后传给downgrade命令:

python xx.py db history

输出格式: -> 版本号 (head), initial migration

回滚到指定版本

python app.py db downgrade 版本号

实际操作顺序:

迁移数据库一般情况下前三步就够了
1.python xx.py db init
2.python xx.py db migrate -m"版本名(注释)"
3.python xx.py db upgrade 然后观察表结构
4.根据需求修改模型
5.python xx.py db migrate -m"新版本名(注释)"
6.python xx.py db upgrade 然后观察表结构
7.若返回版本,则利用 python xx.py db history查看版本号
8.python xx.py db downgrade(upgrade) 版本号

整体代码如下:

from flask import Flask,render_template,request

#flask_script作用是用命令行来管理
from flask_script import Manager
#flask_migrate作用是用来迁移数据库
from flask_migrate import Migrate, MigrateCommand #MigrateCommand迁移指令
from flask_sqlalchemy import SQLAlchemy
import os

app = Flask(__name__)

#生成秘钥
app.secret_key = os.urandom(24)

# #用于连接数据库的URI                  数据库类型   账号密码    ip     端口   数据库名
app.config['SQLALCHEMY_DATABASE_URI']='mysql://root:mysql@127.0.0.1:3306/flask'
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False#这一步非常耗性能(开启追踪)
app.config['DEBUG'] = True


# 创建一个管理数据库对象(句柄),注意参数需要和app产生联系
db = SQLAlchemy(app)            #SQLAlchemy语言的映射关系
manager = Manager(app)
# 第一个参数是Flask的实例,第二个参数是Sqlalchemy数据库实例
migrate = Migrate(app, db)
# manager是Flask-Script的实例,这条语句在flask-Script中添加一个db_command命令
manager.add_command('db', MigrateCommand)

#角色和用户之间,一对多,一个角色可以对应多个用户,一个用户只有一个角色
class Role(db.Model):
    __tablename__ = 'roles'
    id = db.Column(db.Integer,primary_key=True)
    name = db.Column(db.String(20),unique=True)
    
    #在主表加关系,与用户表产生联系,代表的是这个角色下面所有的用户
    # 用到的时候加载关联对象
    users = db.relationship('Users',backref='role',lazy='dynamic')
    
    #加载完成对象之后,立即加载关联对象
    #users = db.relationship('Users',backref='role',lazy='subquery')
    
    def __repr__(self):

        return'<Role %s>' %self.name

# 创建用户类
class Users(db.Model):
    #定义表名
    __tablename__ = 'users'
    #定义列对象
    id = db.Column(db.Integer,primary_key=True)
    name = db.Column(db.String(20),unique=True)
    is_delete = db.Column(db.Boolean,default=False)
    email = db.Column(db.String(30),nullable=True)

    #外键,添加外键的时候需要注意,指定表明和字段
    role_id = db.Column(db.Integer,db.ForeignKey('roles.id'))

    # 这个是返回可读字符串
    def __repr__(self):
        return '<Users %s>' % self.name

if __name__ == '__main__':
    manager.run()
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值