• 用 Flask 来写个轻博客 (8) — (M)VC_Alembic 管理数据库结构的升级和降级


    目录

    前文列表

    用 Flask 来写个轻博客 (1) — 创建项目
    用 Flask 来写个轻博客 (2) — Hello World!
    用 Flask 来写个轻博客 (3) — (M)VC_连接 MySQL 和 SQLAlchemy
    用 Flask 来写个轻博客 (4) — (M)VC_创建数据模型和表
    用 Flask 来写个轻博客 (5) — (M)VC_SQLAlchemy 的 CRUD 详解
    用 Flask 来写个轻博客 (6) — (M)VC_models 的关系(one to many)
    用 Flask 来写个轻博客 (7) — (M)VC_models 的关系(many to many)

    扩展阅读

    Openstack_SQLAlchemy 修改数据库的表结构
    Openstack_SQLAlchemy_一对多关系表的多表插入实现

    Alembic

    大多数情况下,在开始实现一个新项目的代码之前都是先完成数据库的设计。但随着项目新功能的增加或需求变更,不可避免的数据模型的修改会贯穿项目开发的始终。这里会出现一个问题:当把这些数据模型的更新从开发环境迁移到生产环境时,怎样才能在保证原有数据完整性的情况下更新的数据库结构或将数据库回滚到之前的某一个时刻以便复现环境。

    Alembic(Database migration 数据迁移跟踪记录) 提供的数据库升级和降级的功能,就可以帮我们解决上述的问题。它所能实现的效果有如 Git 管理项目代码一般。

    • 在这里我们使用 Flask 的扩展 Flask-Migrate
      NOTE:要在 virtualenv 的环境下安装
    pip install Flask-Migrate
    pip freeze > requirements.txt
    • 生成 manager db 指令
      在 manage.py 文件中 Create a new commands: manager.add_command("db", MigrateCommand)
    from flask.ext.script import Manager, Server
    from flask.ext.migrate import Migrate, MigrateCommand
    
    import main
    import models
    
    
    # Init manager object via app object
    manager = Manager(main.app)
    
    # Init migrate object via app and db object
    migrate = Migrate(main.app, models.db)
    
    # Create some new commands
    manager.add_command("server", Server())
    manager.add_command("db", MigrateCommand)
    
    
    @manager.shell
    def make_shell_context():
        """Create a python CLI.
    
        return: Default import object
        type: `Dict`
        """
        return dict(app=main.app,
                    db=models.db,
                    User=models.User,
                    Post=models.Post,
                    Comment=models.Comment,
                    Tag=models.Tag)
    
    if __name__ == '__main__':
        manager.run()

    查看指令 manager db 的可用选项

    (env) [root@flask-dev JmilkFan-s-Blog]# python manage.py db
    Perform database migrations
    
    positional arguments:
      {upgrade,heads,merge,migrate,stamp,show,current,edit,init,downgrade,branches,history,revision}
        upgrade             Upgrade to a later version
        heads               Show current available heads in the script directory
        merge               Merge two revisions together. Creates a new migration file
        migrate             Alias for 'revision --autogenerate'
        stamp               'stamp' the revision table with the given revision; don't run any migrations
        show                Show the revision denoted by the given symbol.
        current             Display the current revision for each database.
        edit                Edit current revision.
        init                Creates a new migration repository
        downgrade           Revert to a previous version
        branches            Show current branch points
        history             List changeset scripts in chronological order.
        revision            Create a new revision file.

    初始化 DB Migrate

    (env) [root@flask-dev JmilkFan-s-Blog]# python manage.py db init
      Creating directory /opt/JmilkFan-s-Blog/migrations ... done
      Creating directory /opt/JmilkFan-s-Blog/migrations/versions ... done
      Generating /opt/JmilkFan-s-Blog/migrations/README ... done
      Generating /opt/JmilkFan-s-Blog/migrations/alembic.ini ... done
      Generating /opt/JmilkFan-s-Blog/migrations/env.py ... done
      Generating /opt/JmilkFan-s-Blog/migrations/script.py.mako ... done
      Generating /opt/JmilkFan-s-Blog/migrations/env.pyc ... done
      Please edit configuration/connection/logging settings in '/opt/JmilkFan-s-Blog/migrations/alembic.ini' before proceeding.

    在初始化数据库更新任务之后会创建一个 migrations 目录,所有的更改记录文件(这个记录文件本来就是 Python 文件)都会被保存在该目录下。

    开始第一次跟踪

    (env) [root@flask-dev JmilkFan-s-Blog]# python manage.py db migrate -m "Initial migration"
    INFO  [alembic.runtime.migration] Context impl MySQLImpl.
    INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
    INFO  [alembic.env] No changes in schema detected.

    该指令会让 Alembic 扫描所有的 SQLAlchemy 对象,并将没有记录过的行和列记录成为一个 python 文件并保存到 migrations/versions 路径下。

    将记录文件应用到数据库中(实时升级数据库结构)

    NOTE 1: 执行该指令的前提是 migrations/versions 目录下必须存在记录文件。
    NOTE 2: 而且这些记录文件是我们能够手动修改和创建的,这也是实时更新数据库结构的方法。将需要修改的数据库结构的更新内容,手动的写入到记录文件中,然后执行 upgrade 指令就能够实现数据库的更新,而且这些更新是可以批量的作用于数据库中,不需要使用一条一条的 SQL 语句来进行修改。

    (env) [root@flask-dev JmilkFan-s-Blog]# python manage.py db upgrade
    INFO  [alembic.runtime.migration] Context impl MySQLImpl.
    INFO  [alembic.runtime.migration] Will assume non-transactional DDL

    回滚到某一个记录环境中

    用法于 Git 非常相似:

    # 获取 History ID
    (env) [root@flask-dev JmilkFan-s-Blog]# python manage.py db history
    
    
    # 回滚到某个 history
    (env) [root@flask-dev JmilkFan-s-Blog]# python manage.py db downgrade <history_id>
  • 相关阅读:
    dp思维
    快速幂+地推
    背包问题找物品
    石子合并问题
    hihocoder 1580 Matrix(北京icpc2017网络赛)
    ACM对拍造数据
    主席树学习小结(POJ 2104)
    莫队算法入门 BZOJ 2038
    hdu 2586
    Kattis
  • 原文地址:https://www.cnblogs.com/jmilkfan-fanguiju/p/7532281.html
Copyright © 2020-2023  润新知