使用alembic进行数据库版本管理
前言
随着项目业务需求的不断变更,数据库的表结构修改难以避免,此时就需要对数据库的修改加以记录和控制,便于项目的版本管理和随意的升级和降级。
Alembic就可以很好的解决这个问题。Alembic是SQLAlchemy作者开发的Python数据库版本管理工具。
安装
pip install alembic
通过pip命令安装,如果使用虚拟环境,记得激活虚拟环境后再执行pip命令
同时需要安装的还有SQLAlchemy和PyMysql
pip install sqlalchemy
pip install pymysql
初始化
在使用alembic之前,需要进行初始化操作。
alembic init <YOUR_ALEMBIC_DIR>
YOUR_ALEMBIC_DIR,可以取一个符合项目名称规范的目录名,如
alembic init alembic
此时需要注意,如果之前是在虚拟环境中安装的alembic,需要激活虚拟环境后,在执行上述命令。
同时,建议cd到项目根目录再执行初始化操作,因为YOUR_ALEMBIC_DIR会在当前目录下创建。
显示类似结果即初始化成功。
Creating directory D:\Project\py_sqlalchemy_demo\alembic ... done
Creating directory D:\Project\py_sqlalchemy_demo\alembic\versions ... done
Generating D:\Project\py_sqlalchemy_demo\alembic.ini ... done
Generating D:\Project\py_sqlalchemy_demo\alembic\env.py ... done
Generating D:\Project\py_sqlalchemy_demo\alembic\README ... done
Generating D:\Project\py_sqlalchemy_demo\alembic\script.py.mako ... done
Please edit configuration/connection/logging settings in 'D:\\Project\\py_sqlalchemy_demo\\alembic.ini' befor
e proceeding.
初始化成功后,会在执行初始化命令的目录下,生成一个alembic.ini的配置文件,及一个alembic目录,目录名就是之前设置的YOUR_ALEMBIC_DIR。
修改配置文件
接下来对alembic.ini的信息进行修改。
主要修改的是配置文件中的数据库连接部分。
sqlalchemy.url = driver://user:pass@localhost:port/dbname
将配置文件中,此部分替换成对应的数据库连接,这个数据库连接的写法是与SQLAlchemy创建engine时是一样的。
如我在demo中使用的是SQLAlchemy与PyMysql,那数据库连接就是类似如下
mysql+pymysql://demo_user:demo123456@127.0.0.1:3306/demo_db
修改env.py
除修改配置文件外,还需要对YOUR_ALEMBIC_DIR目录下的env.py文件进行修改。
在env.py中,将target_metadata设置成项目的model,使alembic能获取到项目中model定义的信息。
将原先的
target_metadata = None
修改成项目中的model
import os
import sys
# 此处需要将项目路径添加到sys.path,否则from import时找不到models
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + "/../")
from models.base import BaseModel
target_metadata = BaseModel.metadata
创建新版本
用 alembic revision -m+注释 创建数据库版本
alembic revision --autogenerate -m "init db"
运行后,类似如下结果,即创建版本成功
INFO [alembic.runtime.migration] Context impl MySQLImpl.
INFO [alembic.runtime.migration] Will assume non-transactional DDL.
INFO [alembic.autogenerate.compare] Detected removed table 'user'
Generating D:\Project\py_sqlalchemy_demo\alembic\versions\7b55b3d83158_create_tables.py ... done
每次修改过SQLAlchemy的model,执行此命令即可创建对应的版本。
执行成功后,会在项目根目录下的alembic/versions/下生成的对应版本的py文件。命令规则是版本号+注释。(这个命名规则是在配置文件中定义的)
在每次创建新版本后,需要执行将数据库升级到新版本的命令,才能继续更新版本。
变更数据库
在每次创建新版本后,需要执行将数据库升级到新版本的命令,才能继续更新版本
将数据库升级到最新版本
alembic upgrade head
运行结果类似
(venv_win) D:\Project\py_sqlalchemy_demo>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 7b55b3d83158 -> b034414f04cd, create tables02
其中,命令中的head和base特指最新版本和最初版本。当需要对数据库进行升级时,使用upgrade,降级使用downgrade。
将数据库降级到最初版本
alembic downgrade base
将数据库降级到执行版本,使用alembic downgrade+版本号,不包含注释部分
alembic downgrade <version>
如
alembic downgrade 7b55b3d83158
运行结果
INFO [alembic.runtime.migration] Context impl MySQLImpl.
INFO [alembic.runtime.migration] Will assume non-transactional DDL.
INFO [alembic.runtime.migration] Running downgrade b034414f04cd -> 7b55b3d83158, create tables02
升级也是同样的道理,alembic upgrade+版本号
离线更新(生成sql脚本)
在某些不适合在线更新的情况,可以采用生成sql脚本的形式,进行离线更新:
alembic upgrade <version> --sql > migration.sql
如:
alembic upgrade ae1027a6acf --sql > migration.sql
从特定起始版本生成sql脚本:
alembic upgrade <vsersion>:<vsersion> --sql > migration.sql
如:
alembic upgrade 1975ea83b712:ae1027a6acf --sql > migration.sql
如果是数据库降级操作,把upgrade替换为downgrade。
查询当前数据库版本号
在对数据库进行升级或降级后,会在当前操作的数据库中新增一个表;alembic_version。
表中的version_num字段记录了当前的数据库版本号。
清除所有版本
如果需要清除所有的版本,将versions删除掉,同时删除数据库的alembic_version表。
参考资料
http://alembic.zzzcomputing.com/en/latest/tutorial.html
http://blog.csdn.net/wenxuansoft/article/details/50242957
使用alembic进行数据库版本管理的更多相关文章
- [jOOQ中文]3. 数据库版本管理工具Flyway
https://segmentfault.com/a/1190000010526452 在执行数据库迁移时,我们推荐使用jOOQ与Flyway - 数据库迁移轻松. 在本章中,我们将简单的来使用这两个 ...
- 【flyway】开源的数据库版本管理工具【migration】
开源的数据库版本管理工具[migration] 记录
- 在SpringBoot中使用flyway进行数据库版本管理
本文大纲 flyway是什么 能帮助我们解决什么问题 springboot环境下使用flyway flyway的工作原理 一.flyway是什么 Flyway是一个开源的数据库版本管理工具,并且极力主 ...
- flask开发restful api系列(3)--利用alembic进行数据库更改
上面两章,主要讲基本的配置,今天我们来做一个比较有趣的东西,为每个客户加一个头像图片.如果我们图片保存在自己的服务器,对于服务器要求有点高,每次下载的时候,都会阻塞网络接口,要是1000个人同时访问这 ...
- 数据库版本管理工具Flyway——基础篇
Flyway 默认规约 SQL 脚本文件默认位置是项目的源文件夹下的db/migration 目录. Java 代码默认位于db.migration 包. SQL 脚本文件及Java 代码类名必须遵循 ...
- 使用Source Safe for SQL Server解决数据库版本管理问题
简介 在软件开发过程中,版本控制是一个广为人知的概念.因为一个项目可能会需要不同角色人员的参与,通过使用版本控制软件,可以使得项目中不同角色的人并行参与到项目当中.源代码控制使得代码可以存在多 ...
- 使用Source Safe for SQL Server解决数据库版本管理问题(转载)
简介 在软件开发过程中,版本控制是一个广为人知的概念.因为一个项目可能会需要不同角色人员的参与,通过使用版本控制软件,可以使得项目中不同角色的人并行参与到项目当中.源代码控制使得代码可以存在多个版本, ...
- 数据库版本管理工具Flyway(4.0.3)---工作机制(译文)
How Flyway works The easiest scenario is when you point Flyway to an empty database. 最容易的方案是Flyway指向 ...
- 数据库版本管理工具Flyway(4.0.3)---介绍(译文)
Flyway Evolve your Database Schema easily and reliably across all your instances 简单的.可靠的升级(发展)你的数据库模 ...
随机推荐
- 基于 HTML5 Canvas 的 3D 压力器反序列化
在实际应用中,我觉得能够通过操作 JSON 文件来操作 3D 上的场景变化是非常方便的一件事,尤其是在做编辑器进行拖拽图元并且在图元上产生的一系列变化的时候,都能将数据很直观地反应给我们,这边我们简单 ...
- OBS源码解析(1)main函数
int main(int argc, char *argv[]){#ifndef _WIN32 signal(SIGPIPE, SIG_IGN);#endif #ifdef _WIN32 /*Open ...
- 如何设置html中img宽高相同-css
最近项目中有一个问题,做一个响应式的盒子,随着屏幕的变化, 宽高一直保持相等,之前一直使用js动态设置,获取盒子的宽度来设置盒子高度. 但是加载时样式显示不是很好,后来直接用css实现. html部分 ...
- javaweb学习总结(六)——Servlet开发(二)(转)
转载自 http://www.cnblogs.com/xdp-gacl/p/3763559.html 一.ServletConfig讲解 1.1.配置Servlet初始化参数 在Servlet的配置文 ...
- Creational模式之Builder模式
1.意图 将一个复杂对象的构建与它表示分离,使得相同的构建过程能够创建不同的表示. 查看很多其它请点击 2.别名 无 3.动机 一个RTF(Rich Text Format)文档交换格式的阅读器应能将 ...
- 一起读源码之zookeeper(1) -- 启动分析
从本文开始,不定期分析一个开源项目源代码,起篇从大名鼎鼎的zookeeper开始. 为什么是zk,因为用到zk的场景实在太多了,大部分耳熟能详的分布式系统都有zookeeper的影子,比如hbase, ...
- MQTT 简介
MQTT 全称是 Message Queue Telemetry Transport,是一个轻量级的“发布/订阅”消息传输协议. 官网 http://mqtt.org/ 发布/订阅 MQTT 的基本概 ...
- pcre和正则表达式的误点
1.正则中所有的匹配模式,都应该理解为"匹配了某字符或字符串后,紧跟着再匹配".这个概念很重要. 2.中括号首部使用脱字符时,表示的是紧跟着匹配不含给定字符的字符,而不是允许不匹配 ...
- 【java API基本实现】LinkedList
LinkedList: package com.tn.arraylist; public class LinkedList { Node head=null; Node tail=null; int ...
- Python进阶之迭代器和生成器
可迭代对象 Python中任意的对象,只要它定义了可以返回一个迭代器的__iter__方法,或者定义了可以支持下标索引的__getitem__方法,那么它就是一个可迭代对象.简单来说,可迭代对象就是能 ...