UDN-企业互联网技术人气社区

板块导航

浏览  : 2030
回复  : 0

[讨论交流] 前端开发数据库——迁移工具 alembic初步使用

[复制链接]
cat77的头像 楼主
发表于 2016-5-19 14:37:59 | 显示全部楼层 |阅读模式
本帖最后由 cat77 于 2016-5-19 14:41 编辑

  1. 概述

  基于flask框架构建web,一般会使用sqlchemy(在flask中使用sqlchemy可以参考 这里 )作为数据库引擎。

  这样业务的逻辑就可以做到不跟具体的数据库类型相耦合,具体后端业务是使用那种数据库就全凭业务需要了。

  但是数据表结构并不一定是一成不变的,可能随着业务的需要表的结构经常会变换。面对这种情况,单纯删除之前的表,

  重新再建新的表会导致数据的丢失,如果自己迁移又比较麻烦。以为,自己迁移的话,可能只能切到比较新的版本,但是

  想要回滚到之前的版本几乎是不可能的,这样涉及到使用数据库迁移工具了。

  针对flask,有两个比较重要的数据库迁移工具: flask migrate 和 alembic 。flask migrate是基于alembic,但是个人

  感觉flask migrate不够灵活,而且使用alembic还是比较方便的。所以,我这边是直接使用alembic来做为数据库迁移工具的。

  首先,稍微介绍下alembic,alembic是sqlchemy作者一手缔造的,对sqlchemy的兼容性肯定是其他组件根本无法媲美的。

  2. 安装

  安装alembic还是蛮方便的,直接使用python安装工具pip就可以了,具体命令如下:
  1. sudo pip install alembic
复制代码

  3. 初始化

  回到flask application所处目录,执行如下命令:
  1. alembic init alembic
复制代码

  执行成功之后,就能在当前目录看到两个比较重要的文件: alembic.ini 文件和 alembic 目录。

  alembic.ini保存的是alembic的配置信息,而数据库版本信息的记录是在alembic目录下。

  alembic目录的机构如下:
  1. [root@localhost alembic]# ls -trlh
  2. total 16K
  3. -rw-r--r-- 1 root root   38 May 11 19:36 README
  4. -rw-r--r-- 1 root root  494 May 11 19:36 script.py.mako
  5. -rw-r--r-- 1 root root 2.1K May 12 02:43 env.py
  6. drwxr-xr-x 2 root root 4.0K May 12 18:53 versions
复制代码

  这块起作用的有两个,一个是 env.py 文件以及 versions 目录。

  env.py记录着跟环境有关的一些信息,比较起作用的是 target_metadata 这个字段,后面在介绍使用的时候会提到。

  versions目录下面是记录当前数据库所有版本,以及对应操作的python文件。

  每个文件内容大致如下:
  1. """empty message

  2. Revision ID: 27c6a30d7c24
  3. Revises: None
  4. Create Date: 2011-11-08 11:40:27.089406

  5. """

  6. # revision identifiers, used by Alembic.
  7. revision = '27c6a30d7c24'
  8. down_revision = None

  9. from alembic import op
  10. import sqlalchemy as sa

  11. def upgrade():
  12.     pass

  13. def downgrade():
  14.     pass
复制代码

  revision字段记录的是当前文件代表的版本,初始时down_revision为None。具体在使用过程中一般指向的是上一个版本,具体

  在回滚过程中非常有用。默认情况下 upgrade 和 downgrade 都会空。

  在数据库升级或者回滚过程中必须要重写这这个函数,如果要升级就需要重写upgrade函数,回滚就需要重写downgrade函数。

  4. 一个简答的例子

  首先必须更改 alembic.ini 文件中的 sqlalchemy.url 字段,改为你目前在使用的数据路径就OK了。

  此处,我是改为:
  1. sqlalchemy.url = sqlite:////home/dashuju/admin_db.sqlite
复制代码

  这个文件其他字段可以暂时不用更改,目前的设置就可以使用了。

  更改alembic目录下的 env.py 文件,主要是设置 target_metadata 这个字段:
  1. import sys
  2. sys.path.append('.')
  3. from admin_app import db

  4. target_metadata = db.metadata
复制代码

  admin_app是flask application的文件名,db是在flask_app定义的全局变量,

  具体初始化为: db = SQLAlchemy(app)

  更改下versions目录下的当前版本py文件,并根据对应的upgrade和downgrade函数,具体代码如下:
  1. def upgrade():
  2.     op.create_table(
  3.         'users',
  4.         sa.Column('id', sa.Integer, primary_key=True),
  5.         sa.Column('name', sa.String(50), nullable=False),
  6.         sa.Column('description', sa.Unicode(200)),
  7.     )

  8. def downgrade():
  9.     op.drop_table('users')
复制代码

  执行:
  1. alembic upgrade head
复制代码

  指令来升级数据库,查看对应的数据库,可以看到数据库中多了一个users表。

  查看versions目录下的文件,会发现多了一个py文件。可以在flask application所在目录执行:

  alembic current来查看当前数据库所处版本,也可以使用alembic history来查看数据库变更的历史记录。

  如果想要回滚,也可以使用 alemibic downgrade -1 指令来回滚数据库到之前的版本。

  更改表结构

  对于想要更改表结构,比如插入column或者删除column,删除column可能特殊些,所以要讲下:

  插入行,一般如下:
  1. op.add_column('users', sa.Column('id', sa.INTEGER(), nullable=True))
复制代码

  删除行,可能特殊些,具体如下:
  1. with op.batch_alter_table('users') as batch_op:
  2.         batch_op.drop_column('id')
复制代码

  想要删除多列,可以在with语句下增加多行就可以了,否则会报错:
  1. sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) near "DROP": syntax error [SQL: u'ALTER TABLE posts DROP COLUMN XXX']
复制代码

相关帖子

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关于我们
联系我们
  • 电话:010-86393388
  • 邮件:udn@yonyou.com
  • 地址:北京市海淀区北清路68号
移动客户端下载
关注我们
  • 微信公众号:yonyouudn
  • 扫描右侧二维码关注我们
  • 专注企业互联网的技术社区
版权所有:用友网络科技股份有限公司82041 京ICP备05007539号-11 京公网网备安1101080209224 Powered by Discuz!
快速回复 返回列表 返回顶部