前言
通常我们会将我们的代码放入到某个VCS(版本控制系统)中,进行可追溯的版本管理。一个项目除了代码,通常还会有一个数据库,这个数据库可能会随着项目的演进发生变化,甚至需要可以回滚到过去的某个状态,于是一些工具将数据库的版本化也纳入了管理。
Alembic
是Sqlalchemy
的作者实现的一个数据库版本化管理工具,它可以对基于Sqlalchemy的Model与数据库之间的历史关系进行版本化的维护。
开始
安装
pip install alembic
初始化
alembic init alembic
执行后会在工程目录下生成以下的目录结构:
.
├── alembic
│ ├── env.py # 配置DataBase.metadata
│ ├── README
│ ├── script.py.mako # 迁移脚本生成模版
│ └── versions # 版本更新(迁移脚本)的内容目录
└── alembic.ini # 配置数据库
数据库模板类
# ./database.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+mysqldb://user_name:password@localhost:3306/database_name'
db = SQLAlchemy(app)
...emmmm...
配置
- alembic.ini
- 改
sqlalchemy.url = driver://user:pass@localhost/dbname
- 为
mysql+mysqldb://user_name:password@localhost:3306/database_name
- 改
- alembic/env.py
- 改
target_metadata = None
为以下内容:
- 改
import sys
from database import db
# 这个路径要改为数据库模板类所在的目录下
# dirname(dirname(abspath(__file__))) -> ./alembic
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + "/../")
from db import db
target_metadata = db.metadata
使用
这东西好处就是可以像Git一样升级和降级数据库。
- 这个工具是按照数据库来判断你是否要对数据库进行升级。因此,参照物是数据库表,而变化的是你写的代码。
创建数据库版本[手写]
alembic revision -m "注释"
-m
:注释- 缺点:手写……
跑完之后会在./alembic/versions
生成脚本。
alembic
├── env.py
├── README
├── script.py.mako
└── versions
└── 6f406f586bbb_注释.py
脚本内容如下所示:
"""注释
Revision ID: 6f406f586bbb
Revises: 8b6caa4ac725
Create Date: 2019-05-14 20:06:39.940623
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '6f406f586bbb'
down_revision = '8b6caa4ac725'
branch_labels = None
depends_on = None
def upgrade():
pass
def downgrade():
pass
创建一个新表
Operations的文档:Operation Reference
...省略...
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')
修改表
"""Add a column
Revision ID: ae1027a6acf
Revises: 1975ea83b712
Create Date: 2011-11-08 12:37:36.714947
"""
# revision identifiers, used by Alembic.
revision = 'ae1027a6acf'
down_revision = '1975ea83b712'
from alembic import op
import sqlalchemy as sa
def upgrade():
op.add_column('account', sa.Column('last_transaction_date', sa.DateTime))
def downgrade():
op.drop_column('account', 'last_transaction_date')
总而言之,你可以用Alembic来创建和修改表的结构。
创建数据库版本[自动]
alembic revision --autogenerate -m "initdb"
- 自动生成数据库版本
- 说明:当且仅当数据库为空的时候才会自动根据创建的Model创建version版本。
没有数据库表
没有数据库的时候,Alembic会根据模型创建,命令行执行的结果:
INFO [alembic.runtime.migration] Context impl MySQLImpl.
INFO [alembic.runtime.migration] Will assume non-transactional DDL.
INFO [alembic.autogenerate.compare] Detected added table '...'
INFO [alembic.autogenerate.compare] Detected added table '...'
INFO [alembic.autogenerate.compare] Detected added table '...'
INFO [alembic.autogenerate.compare] Detected added table '...'
INFO [alembic.autogenerate.compare] Detected added table '...'
Generating /.../project_name/alembic/versions/5e2d2560b497_init_db.py ... done
看看文件内容:
"""init db
Revision ID: 5e2d2560b497
Revises:
Create Date: 2019-05-15 11:11:14.684351
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '5e2d2560b497'
down_revision = None
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('...'