首页 > 编程知识 正文

Alembic 简明教程,大学物理简明教程第四版

时间:2023-05-06 11:33:27 阅读:186987 作者:4005

本文记录了Alembic的主要使用过程。

数据库版本

通常,将我们的代码放入某个VCS (版本控制系统)中,进行可追溯性的版本控制。 一个项目不仅有代码,而且通常有数据库。 该数据库可能会随着项目的进展而变化,还必须能够回滚到过去的某个状态。 因此,一些工具还将数据库版本化纳入管理。

Alembic是Sqlalchemy作者实现的数据库版本控制工具,用于管理基于Sqlalchemy的模型和数据库之间的历史关系。

雷姆BIC

可以直接从PIP install alembic安装。 需要三个依赖包,pip会自动处理。

SQLAlchemy和作者的ORM工具

Mako和作者模板工具

标记安全将标记转换为HTML的组件

初始化

在你的项目路线上执行

alembic init YOUR_ALEMBIC_DIR

然后,alembic.ini文件和YOUR_ALEMBIC_DIR目录应该会被添加到项目目录中。 请指定适合自己项目风格的名称。

以下操作均以此目录为中心。

yourproject/

alembic.ini

YOUR_ALEMBIC_DIR/

env.py

自述

script.py.mako

版本/

3512b954651e_add_account.py

2b1ae634e5cd_add_order_id.py

3 adcc 9a 56557 _ rename _ username _ field.py

alembic.ini提供了基本配置

env.py在每次运行Alembic时都会加载此模块,主要提供与项目Sqlalchemy Model的连接

script.py.mako迁移脚本生成模板

versions包含生成的迁移脚本目录

除了基本的Alembic项目外,还可以指定一些特殊的项目模板。

$ alembic list_templates

可用模板:

通用单一数据库配置。

多数据库配置。

pylons -配置hatreadsfromapylonsprojectenvironment。

templatesareusedviathe ' init ' command,e.g.

alembicinit---- template pylons./scripts

必须编辑Alembic.ini文件以指定alembic的数据库连接。

# templateusedtogeneratemigrationfile

#file_template=%%%(rev ) s_%% ) slug ) s

# setto ' true ' toruntheenvironmentduring

# the 'revision' command,regardless of auto generate

# revision_environment=false

sqlalchemy.URL=driver ://user : pass @ localhost/dbname

#记录配置

[loggers]

keys=root,sqlalchemy,alembic

版本

首先制作基本的数据库版本。 当然,可以从现有的数据库出发。

$ alembicrevision-m ' create account table '

gene rating/path/to/your project/your _ alem BIC _ dir/versions/1975 ea83b 712 _ create _ acco _ n

t_table.py.done

生成的版本文件如下所示:

“”创建帐户表

Revision ID: 1975ea83b712

Revises: None

create date :2011-11-0811:40336027.089406

“”'

# revision identifiers,used by Alembic。

revision='1975ea83b712 '

降级

n_revision = None
from alembic import op
import sqlalchemy as sa
def upgrade():
    pass
def downgrade():
    pass

其中 revision = '1975ea83b712'和down_revision = None指定了这个reversion的当前版本号,以及父版本号,就是通过这个进行追溯。

然后我们修改upgrade和downgrade进行实际的升降级操作。通过易用的API,我们只需要对op和sa对象进行操作即可。

def upgrade():
    op.create_table(
        'account',
        sa.Column('id', sa.Integer, primary_key=True),
        sa.Column('name', sa.String(50), nullable=False),
        sa.Column('description', sa.Unicode(200)),
    )
def downgrade():
    op.drop_table('account')

具体op所支持的操作请看操作API引用。
升级,降级

然后我们更新好最新的版本。

$ alembic upgrade head
INFO [alembic.context] Context class PostgresqlContext.
INFO [alembic.context] Will assume transactional DDL.
INFO [alembic.context] Running upgrade None -> 1975ea83b712

一般我们需要指定版本号进行升级,但是对于最新以及最初版本有两个额外的别名,head指最新版本,base指最初的版本。

降级也很简单,只要upgrade以及downgrade实现足够鲁棒。

$ alembic downgrade base
INFO [alembic.context] Context class PostgresqlContext.
INFO [alembic.context] Will assume transactional DDL.
INFO [alembic.context] Running downgrade 1975ea83b712 -> None

自动生成迁移脚本

Alembic 不仅仅能够维护数据库历史版本,而且带来这个新奇的特性,自动生成迁移脚本。

通常我们进行编码时候,在确定需求后,通常需要对数据模型进行变化。
不要担心,只要不是出于技术实现问题,诸如长度过少数据类型应用错等。而是因为业务的变更而导致的数据模型变更完全可以理解。"程序=算法+数据结构“,业务逻辑发生了变化,实现算法、数据结构必然发生变化,不要贪图抽象隔离设计之类云云,这类除了使得程序复杂度增加之外,很难保证未来预期是否如之前所设计的工作量完全可以避免。

口头商量,确定方案,然后开始打算修改,除了设计稿之外,往往最先实现的是ORM中我们的实体类,因为他们简单易懂。
在此例中我因为需要给用户添加微博OAuth2.0的绑定,所以新增了两个字段:

class User(Base):
    # …. origin others setting
    weibo_token = Column(String(64), nullable=True)
    weibo_expires = Column(DateTime, nullable=True)

这个时候直接运行程序必然会失败,因为映射关系已经被打乱了,我们需要重建这个关系。

配置YOUR_ALEMBIC_DIR/env.py文件,修改target_metadata = None为你的元信息对象。
这里我就直接导入了,但是在导入的过程中由于目录问题,所以一个额外的Hack。

# Hack for model import
import os
import sys
sys.path.insert(0, os.path.realpath("."))
# add your model's MetaData object here
# for 'autogenerate' support
# from myapp import my model
# target_metadata = None
from model import Base
target_metadata = Base.metadata

见证奇迹的时刻:

$ alembic revision --autogenerate -m "add weibo token fields for user"
INFO [alembic.migration] Context impl MySQLImpl.
INFO [alembic.migration] Will assume non-transactional DDL.
INFO [alembic.autogenerate] Detected added column 'user.weibo_expires'
INFO [alembic.autogenerate] Detected added column 'user.weibo_token'
  Generating migrate/versions/3117ba3f1f1f_add_weibo_token_expires_for_user.py...done

剩下的就可以按照正常的Alembic操作进行升降级了,是不是把烦人的数据库结构变更问题解决了?当然,这些问题可能在其他生态圈中根本不是问题(Java/Hibernate,Ruby/RoR)。 别忘了将这些变更提交到VCS中,他们可是非常值得你去维护。
自动迁移脚本生成功能实现

你可以在Alembic的源码的autogenerate.py模块中找到,一共近七百行。
程序流程如下: d.png

写得挺流水的,没有抽象,至少_compare_*都只是对于两个集合差集的提取,以及交集的迭代,这部分是可以很容易抽象出来的。
得到差异后,再对差异数据进行“渲染”,既有原地执行,也有渲染输出为Sql,还能对升降级进行不同的输出。
Sqlalchemy-migrate

Sqlalchemy-migrate 借鉴RoR的思路,对数据库进行版本化管理。但是只是提供了基本的功能,对于多个数据库引擎的差异暴露给了开发者,不易用。
命令行的控制细节也挺多了,和Sqlalchemy似乎不是一个思路。 这里就有一个StackOverflow的用户在抱怨难以上手。

alembic revision --autogenerate -m "add machine state"

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。