flask从入门到精通之使用flask-migrate实现数据库迁移

木易森林 木易森林     2022-10-13     430

关键词:

  在开发程序的过程中,你会发现有时需要修改数据库模型,而且修改之后还需要更新数据库。仅当数据库表不存在时,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:

pip install flask-migrate

  这个扩展的初始化方法如下所示:

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 文件夹,所有迁移脚本都存放其中。数据库迁移仓库中的文件要和程序的其他文件一起纳入版本控制。

二.创建迁移脚本

  在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 usys_user
INFO  [alembic.autogenerate.compare] Detected removed table usys_role_privilege
INFO  [alembic.autogenerate.compare] Detected removed table usys_role
INFO  [alembic.autogenerate.compare] Detected removed table usys_privilege
INFO  [alembic.autogenerate.compare] Detected removed table usys_dict
INFO  [alembic.autogenerate.compare] Detected removed table uuser info
INFO  [alembic.autogenerate.compare] Detected removed table ucountry
INFO  [alembic.autogenerate.compare] Detected removed table usys_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 命令能把改动应用到数据库中,且不影响其中保存的数据。

  

  

 

flask从入门到精通之链接的使用

  在Web开发中,任何具有多个路由的程序都需要可以连接不同页面的链接,例如导航条。  在模板中直接编写简单路由的URL链接不难,但对于包含可变部分的动态路由,在模板中构建正确的URL就很困难。而且,直接编写URL会... 查看详情

flask从入门到精通之大型程序的结构一

  尽管在单一脚本中编写小型Web程序很方便,但这种方法并不能广泛使用。程序变复杂后,使用单个大型源码文件会导致很多问题。不同于大多数其他的Web框架,Flask并不强制要求大型项目使用特定的组织方式,程序结构的组... 查看详情

flask从入门到精通之模型定义

  模型这个术语表示程序使用的持久化实体。在ORM中,模型一般是一个Python类,类中的属性对应数据库表中的列。  Flask-SQLAlchemy创建的数据库实例为模型提供了一个基类以及一系列辅助类和辅助函数,可用于定义模型的结... 查看详情

flask从入门到精通之静态文件

  Web程序不是仅由Python代码和模板组成。大多数程序还会使用静态文件,例如HTML代码中引用的图片、JavaScript源码文件和CSS。  在前面的章节中,我们曾检查hello.py程序的URL映射时,其中有一个static路由。这是因为对静态文... 查看详情

flask从入门到精通之自定义错误界面

  如果你在浏览器的地址栏中输入了不可用的路由,那么会显示一个状态码为404的错误页面。现在这个错误页面太简陋、平庸,而且样式和使用了Bootstrap的页面不一致。  像常规路由一样,Flask允许程序使用基于模板的自定... 查看详情

flask从入门到精通之使用flask-migrate实现数据库迁移

  在开发程序的过程中,你会发现有时需要修改数据库模型,而且修改之后还需要更新数据库。仅当数据库表不存在时,Flask-SQLAlchemy才会根据模型进行创建。因此,更新表的唯一方式就是先删除旧表,不过这样做会丢失数据... 查看详情

flask从入门到精通之大型程序的结构二

一.程序包  程序包用来保存程序的所有代码、模板和静态文件。我们可以把这个包直接称为app(应用),如果有需求,也可使用一个程序专用名字。templates和static文件夹是程序包的一部分,因此这两个文件夹被移到了app中。... 查看详情

flask框架从入门到精通之扩展脚本(十五)(代码片段)

一、概况通过使用Flask-Script扩展,我们可以在Flask服务器启动的时候,通过命令行的方式传入参数。而不仅仅通过app.run()方法中传参,比如我们可以通过pythonscript_flask.pyrunserver--hostip地址,告诉服务器在哪个网络接... 查看详情

flask框架从入门到精通之模板表单(二十)(代码片段)

知识点:1、WTF使用一、概况当前端使用form表单进行参数传递时候,前端一般都会用js来校验用户输入的参数是否合法。作为后端,不能依赖前端的校验。要在前端校验的基础上在进行一遍校验,防止程序出现异常... 查看详情

flask框架从入门到精通之异常处理(代码片段)

知识点:1、abort()函数2、自定义状态码一、概况我们在写视图函数时,会对前端传递过来的参数进行校验,如果校验不过,会给前端返回一些特定的异常信息。在Flask中,abort()函数可以立即终止视图函数的执... 查看详情

flask框架从入门到精通之session(代码片段)

知识点:1、Session一、概况上一篇,我们说到cookie,除了cookie外还有一个叫session的机制。session也是可以存储一些信息的。对于一些敏感、重要的信息,我们可以存储到session中。谁也不希望自己的余额、银行卡密... 查看详情

flask框架从入门到精通之模型迁移操作(十六)(代码片段)

知识点:1、模型迁移一、概况在Django框架开发过程中,我们对数据库字段添加或删除,直接修改模型类,然后进行迁移可以了,非常方便。我们也想让Flask框架支持这样的操作,就需要使用Flask-Migrate扩展&#... 查看详情

flask框架从入门到精通之消息闪现和日志记录(二十一)(代码片段)

知识点:1、闪现2、日志一、概况Flask提供了一个功能方便向前端反馈消息,这个功能叫闪现。闪现的功能是基于session实现,所以我们在使用闪现的时候需要配置secret_key。二、使用我们用一个上传图片的例子来实现闪... 查看详情

flask框架从入门到精通之模板导入与继承(十八)(代码片段)

知识点:1、模板导入2、模板继承一、概况模板导入就是将另一个模板加载到当前模板中,直接渲染。模板继承和类的继承含义是一样的,主要是为了提高代码重用,减轻开发人员的工作量。典型应用:网站的... 查看详情

flask框架从入门到精通之模板导入与继承(十八)(代码片段)

知识点:1、模板导入2、模板继承一、概况模板导入就是将另一个模板加载到当前模板中,直接渲染。模板继承和类的继承含义是一样的,主要是为了提高代码重用,减轻开发人员的工作量。典型应用:网站的... 查看详情

flask框架从入门到精通之模型查询(十三)(代码片段)

知识点:1、模型查询一、查询其实我们对模型的主要操作就是查询,在Flask-SQLAlchemy中,支持了很多的查询方法。查询操作是通过query对象操作数据。最基本的查询是返回表中所有数据,可以通过过滤器进行更精确... 查看详情

flask框架从入门到精通之蓝图(二十四)(代码片段)

知识点:1、蓝图一、概况从前面的知识点能看出来,我们所有的视图函数都写在了一个文件当中,当我们的业务越来复杂的时候。视图函数也会变得越来越多,导致阅读不方便,维护起来困难等难题。比如下... 查看详情

flask从入门到精通之flask-moment本地化日期和时间

  Moment.js是一个简单易用的轻量级JavaScript日期处理类库,提供了日期格式化、日期解析等功能。它支持在浏览器和NodeJS两种环境中运行。此类库能够将给定的任意日期转换成多种不同的格式,具有强大的日期计算功能,同时... 查看详情