Python 实现数据库更新脚本的生成方法
作者:jingxian 发布时间:2024-01-15 22:35:43
标签:python,数据库,生成脚本
我在工作的时候,在测试环境下使用的数据库跟生产环境的数据库不一致,当我们的测试环境下的数据库完成测试准备更新到生产环境上的数据库时候,需要准备更新脚本,真是一不小心没记下来就会忘了改了哪里,哪里添加了什么,这个真是非常让人头疼。因此我就试着用Python来实现自动的生成更新脚本,以免我这烂记性,记不住事。
主要操作如下:
1.在原先 basedao.py 中添加如下方法,这样旧能很方便的获取数据库的数据,为测试数据库和生产数据库做对比打下了基础。
def select_database_struts(self):
'''
查找当前连接配置中的数据库结构以字典集合
'''
sql = '''SELECT COLUMN_NAME, IS_NULLABLE, COLUMN_TYPE, COLUMN_KEY, COLUMN_COMMENT
FROM information_schema.`COLUMNS`
WHERE TABLE_SCHEMA="%s" AND TABLE_NAME="{0}" '''%(self.__database)
struts = {}
for k in self.__primaryKey_dict.keys():
self.__cursor.execute(sql.format(k))
results = self.__cursor.fetchall()
struts[k] = {}
for result in results:
struts[k][result[0]] = {}
struts[k][result[0]]["COLUMN_NAME"] = result[0]
struts[k][result[0]]["IS_NULLABLE"] = result[1]
struts[k][result[0]]["COLUMN_TYPE"] = result[2]
struts[k][result[0]]["COLUMN_KEY"] = result[3]
struts[k][result[0]]["COLUMN_COMMENT"] = result[4]
return self.__config, struts
2.编写对比的Python脚本
'''
数据库迁移脚本, 目前支持一下几种功能:
1.生成旧数据库中没有的数据库表执行 SQL 脚本(支持是否带表数据),生成的 SQL 脚本在 temp 目录下(表名.sql)。
2.生成添加列 SQL 脚本,生成的 SQL 脚本统一放在 temp 目录下的 depoyed.sql 中。
3.生成修改列属性 SQL 脚本,生成的 SQL 脚本统一放在 temp 目录下的 depoyed.sql 中。
4.生成删除列 SQL 脚本,生成的 SQL 脚本统一放在 temp 目录下的 depoyed.sql 中。
'''
import json, os, sys
from basedao import BaseDao
temp_path = sys.path[0] + "/temp"
if not os.path.exists(temp_path):
os.mkdir(temp_path)
def main(old, new, has_data=False):
'''
@old 旧数据库(目标数据库)
@new 最新的数据库(源数据库)
@has_data 是否生成结构+数据的sql脚本
'''
clear_temp() # 先清理 temp 目录
old_config, old_struts = old
new_config, new_struts = new
for new_table, new_fields in new_struts.items():
if old_struts.get(new_table) is None:
gc_sql(new_config["user"], new_config["password"], new_config["database"], new_table, has_data)
else:
cmp_table(old_struts[new_table], new_struts[new_table], new_table)
def cmp_table(old, new, table):
'''
对比表结构生成 sql
'''
old_fields = old
new_fields = new
sql_add_column = "ALTER TABLE `{TABLE}` ADD COLUMN `{COLUMN_NAME}` {COLUMN_TYPE} COMMENT '{COLUMN_COMMENT}';\n"
sql_change_column = "ALTER TABLE `{TABLE}` CHANGE `{COLUMN_NAME}` `{COLUMN_NAME}` {COLUMN_TYPE} COMMENT '{COLUMN_COMMENT}';\n"
sql_del_column = "ALTER TABLE `{TABLE}` DROP {COLUMN_NAME};"
if old_fields != new_fields:
f = open(sys.path[0] + "/temp/deploy.sql", "a", encoding="utf8")
content = ""
for new_field, new_field_dict in new_fields.items():
old_filed_dict = old_fields.get(new_field)
if old_filed_dict is None:
# 生成添加列 sql
content += sql_add_column.format(TABLE=table, **new_field_dict)
else:
# 生成修改列 sql
if old_filed_dict != new_field_dict:
content += sql_change_column.format(TABLE=table, **new_field_dict)
pass
# 生成删除列 sql
for old_field, old_field_dict in old_fields.items():
if new_fields.get(old_field) is None:
content += sql_del_column.format(TABLE=table, COLUMN_NAME=old_field)
f.write(content)
f.close()
def gc_sql(user, pwd, db, table, has_data):
'''
生成 sql 文件
'''
if has_data:
sys_order = "mysqldump -u%s -p%s %s %s > %s/%s.sql"%(user, pwd, db, table, temp_path, table)
else:
sys_order = "mysqldump -u%s -p%s -d %s %s > %s/%s.sql"%(user, pwd, db, table, temp_path, table)
os.system(sys_order)
def clear_temp():
'''
每次执行的时候调用这个,先清理下temp目录下面的旧文件
'''
if os.path.exists(temp_path):
files = os.listdir(temp_path)
for file in files:
f = os.path.join(temp_path, file)
if os.path.isfile(f):
os.remove(f)
print("临时文件目录清理完成")
if __name__ == "__main__":
test1_config = {
"user" : "root",
"password" : "root",
"database" : "test1",
}
test2_config = {
"user" : "root",
"password" : "root",
"database" : "test2",
}
test1_dao = BaseDao(**test1_config)
test1_struts = test1_dao.select_database_struts()
test2_dao = BaseDao(**test2_config)
test2_struts = test2_dao.select_database_struts()
main(test2_struts, test1_struts)
目前只支持了4种SQL脚本的生成。


猜你喜欢
- 本文实例为大家分享了vue实现表单录入的具体代码,供大家参考,具体内容如下最终效果:代码:<template> <div
- vue切换“页面”(路由)时保持滚动条回到顶部vue项目做pc端的时候,发现在两个页面切换时 滚动条
- 首先,"/"左倾斜是正斜杠,"\"右倾斜是反斜杠,可以记为:除号是正斜杠一般来说对于目录分隔符,Un
- 正则表达式简介正则表达式,又称正规表示式、正规表示法、正规表达式、规则表达式、常规表示法(英语:Regular Expression,在代码
- 一、概述有时候会在一台主机上安装多个不同的Python版本,用以运行不同时期开发的项目, 而在这些不同的Python版本上有时又会加装不同的
- 方法一:<script language="JavaScript"> <!--
- reshape(shape) : 不改变数组元素,返回一个shape形状的数组,原数组不变。是对每行元素进行处理resize(shape)
- 2020.2.20 更新日志:本文的初衷是因为安装anaconda的时候你并不知道会包含哪个版本的python,因此我制作了下表如果你使用的
- 我们通过模拟随机漫步可以说明如何运用数组运算。通过内置的random模块以纯Python的方式实现1000步的随机漫步根据前100个随机漫步
- settings文件中配置:LOGGING = { 'version':1, 'disabl
- 本文为大家分享了python3.5.1安装教程的具体步骤,供大家参考,具体内容如下首先,找到python下载的地址,如下图所示在这里我选择了
- 1.绘制面积图面积图常用于描述某指标随时间的变化程度。其面积也通常可以有一定的含义。绘制面积图使用的是plt.stackplot()方法。以
- 如何为list实现find方法string类型的话可用find方法去查找字符串位置:a_list.find('a')如果找到
- 一、修改表格数据类型 DataFrame 列的顺序实战场景:Pandas 如何修改表格数据类型 DataFrame 列的顺序1.1
- ASP实现即时显示当前页面浏览人数online.asp文件 <!--#include file="dbconn.a
- OR、in和union all 查询效率到底哪个快?网上很多的声音都是说union all 快于 or、in,因为or、in会导致全表扫描,
- 需要的软件phpStudy 用来导入一个数据库api-server 数据库功能可以开启一个服务器,让开发环境可以使用生产环境的网址请求安装
- 1. 域名查询万网提供了域名查询接口,接口采用HTTP协议:接口URL:http://panda.www.net.cn/cgi-bin/ch
- 系列文章:PyQt5使用mimeData实现拖拽事件教程示例解析上实现思路1、简要介绍QMimeData2、QMimeData的用例1:在Q
- 在获得网页响应对象res后,使用res.text属性可以获得网页源代码,但可能出现乱码!因为requests库会使用自动猜测的解码方式将抓取