简介
alembic 主要是用来对数据库升级、迁移等管理的python 库。
重要提示:alembic 不支持直接修改表名称、列名称。其处理的方案是新增一个表、字段 后删除原有的;
这样的结果会造成!!!数据丢失的严重后果!!!
即:所有修改字段名称,表名 的操作,用命令行生成版本脚本后必须 进行review ,将删除,添加操作注释后,手动添加upgrade 和downgrade 函数中的alter 操作!!!
每次操作alembic 会在数据库中记录相应的当前版本号。
谨慎操作!!!
操作流程:
1. 针对修改字段名称的,可以手动修改version 文件,把add_column , drop_column 替换为alter_colunm
2. 针对修改关联字段操作,可以先添加新的字段,然后切换相关的关联信息,然后在下一个版本中删除该字段
安装
pip install alembic
初始化
初始化alembic 仓库: 在终端中, cd 到你的项目目录中,然后执行命令 alembic init
alembic ,创建一个名叫 alembic 的仓库。
alembic init alembic # 后面这个alembic是仓库名称

修改配置文件
- 在 alembic.ini 中设置数据库的连接
# sqlalchemy.url =driver://user:pass@localhost/dbname
sqlalchemy.url = mysql+mysqlconnector://user:xxxxxxxxxxx@10.150.1.xxx:xxxx/db_dev?charset=utf8
# 备注当前pymysql 是支持mysql8.0 的,所以,这个链接链接 相应的可以改为
sqlalchemy.url = mysql+pymysql://user:xxxxxxxxxxx@10.150.1.xxx:xxxx/db_dev?charset=utf8
- 配置model
在env.py 中导入当前项目的model 文件、并且修改target_metadataimport os,sys sys.path.append(os.path.dirname(os.path.dirname(__file__))) import your_models
项目的env.py 配置
# add your model's MetaData object here # for 'autogenerate' support # from myapp import mymodel # target_metadata = mymodel.Base.metadata import os,sys sys.path.append(os.path.dirname(os.path.dirname(__file__))) from db import models target_metadata = models.Base.metadata
- 可配性检查
alembic 默认是不检查字段类型 和 字段默认值;如果需要则要进行配置
compare_type: 默认值False 不检查 字段类型
True 检查字段类型的变化
compare_server_default: 默认值 False 不检查字段默认值变化
True: 检查字段默认值变化
def run_migrations_online():
"""Run migrations in 'online' mode.
In this scenario we need to create an Engine
and associate a connection with the context.
"""
connectable = engine_from_config(
config.get_section(config.config_ini_section),
prefix="sqlalchemy.",
poolclass=pool.NullPool,
)
with connectable.connect() as connection:
context.configure(
connection=connection,
target_metadata=target_metadata,
compare_type=True, # 自行配置
compare_server_default = True # 自行配置
)
自动生成版本变化文件
alembic revision --autogenerate -m "message" 将当前模型中的状态生成迁移文件
执行完成后,在alembic/version 下会生成一个当前的版本变化脚本
注意:由于alembic 不支持字段名称、表名称的修改,【alembic 的处理方案是 删除重建,这样会出造成数据丢失的问题】 所以针对修改字段名称、表名称 的操作,必须手动修改version 生成的当前版本文件
版本文件
"""message
Revision ID: 75c87a72da7b
Revises: bfaba019e9e2
Create Date: 2021-05-28 16:28:39.316000
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import mysql
# revision identifiers, used by Alembic.
revision = '75c87a72da7b'
down_revision = 'bfaba019e9e2'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
# op.add_column('edge', sa.Column('uuid', sa.String(length=100), nullable=True))
# op.drop_column('edge', 'uid')
op.alter_column('edge', 'uid', new_column_name='uuid', existing_type=sa.String(60))
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
# op.add_column('edge', sa.Column('uid', mysql.VARCHAR(length=60), nullable=True))
# op.drop_column('edge', 'uuid')
op.alter_column('edge', 'uuid', new_column_name='uid', existing_type=sa.String(60))
# ### end Alembic commands ###
升级
alembic upgrade head
执行该命令,进行正常迁移到当前版本【由down_v --> curr version】
(sdwan_project) E:\workspace\a_gitlab_projects\sdwan\patrol>alembic upgrade head
INFO [alembic.runtime.migration] Context impl MySQLImpl.
INFO [alembic.runtime.migration] Will assume non-transactional DDL.
INFO [alembic.runtime.migration] Running upgrade bfaba019e9e2 -> 75c87a72da7b, message
回滚
alembic downgrade down_v
回滚到上一个版本;即执行当前版本中的downgrade 函数 【version ---> down_v 】
升级到指定版本
alembic upgrade version