Python 实现数据库(SQL)更新脚本的生成方法


Posted in Python onJuly 09, 2017

我在工作的时候,在测试环境下使用的数据库跟生产环境的数据库不一致,当我们的测试环境下的数据库完成测试准备更新到生产环境上的数据库时候,需要准备更新脚本,真是一不小心没记下来就会忘了改了哪里,哪里添加了什么,这个真是非常让人头疼。因此我就试着用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脚本的生成。

总结

以上所述是小编给大家介绍的Python 实现数据库(SQL)更新脚本的生成方法,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

Python 相关文章推荐
Python实现删除文件但保留指定文件
Jun 21 Python
python面向对象_详谈类的继承与方法的重载
Jun 07 Python
Python 文件操作的详解及实例
Sep 18 Python
Python读取excel中的图片完美解决方法
Jul 27 Python
Python pyinotify模块实现对文档的实时监控功能方法
Oct 13 Python
Python列表与元组的异同详解
Jul 02 Python
Python中的self用法详解
Aug 06 Python
Python列表切片常用操作实例解析
Dec 16 Python
在django中使用apscheduler 执行计划任务的实现方法
Feb 11 Python
Python基于class()实现面向对象原理详解
Mar 26 Python
Python实现一个简单的毕业生信息管理系统的示例代码
Jun 08 Python
4种非常实用的python内置数据结构
Apr 28 Python
解决python文件字符串转列表时遇到空行的问题
Jul 09 #Python
python3 shelve模块的详解
Jul 08 #Python
Python基于scapy实现修改IP发送请求的方法示例
Jul 08 #Python
Python开发微信公众平台的方法详解【基于weixin-knife】
Jul 08 #Python
python 中random模块的常用方法总结
Jul 08 #Python
Python调用微信公众平台接口操作示例
Jul 08 #Python
HTML中使用python屏蔽一些基本功能的方法
Jul 07 #Python
You might like
PHP的Laravel框架中使用AdminLTE模板来编写网站后台界面
2016/03/21 PHP
php制作基于xml的RSS订阅源功能示例
2017/02/08 PHP
Laravel5.7 数据库操作迁移的实现方法
2019/04/12 PHP
js用拖动滑块来控制图片大小的方法
2015/02/27 Javascript
浅谈JavaScript事件的属性列表
2015/03/01 Javascript
JavaScript获取按钮所在form表单id的方法
2015/04/02 Javascript
Vue获取DOM元素样式和样式更改示例
2017/03/07 Javascript
JS数组去重(4种方法)
2017/03/27 Javascript
jQuery UI Grid 模态框中的表格实例代码
2017/04/01 jQuery
angular.js中解决跨域问题的三种方式
2017/07/12 Javascript
vue 2.0项目中如何引入element-ui详解
2017/09/06 Javascript
JavaScript模拟实现封装的三种方式及写法区别
2017/10/27 Javascript
浅谈Vuex@2.3.0 中的 state 支持函数申明
2017/11/22 Javascript
[40:50]2014 DOTA2国际邀请赛中国区预选赛 5 23 CIS VS LGD第四场
2014/05/24 DOTA
[05:22]DOTA2 2015国际邀请赛中国区预选赛首日TOP10
2015/05/26 DOTA
[01:01:52]完美世界DOTA2联赛PWL S2 GXR vs Magma 第二场 11.25
2020/11/26 DOTA
go和python调用其它程序并得到程序输出
2014/02/10 Python
Python的collections模块中的OrderedDict有序字典
2016/07/07 Python
python 中的divmod数字处理函数浅析
2017/10/17 Python
用python的requests第三方模块抓取王者荣耀所有英雄的皮肤实例
2017/12/14 Python
使用python的pexpect模块,实现远程免密登录的示例
2019/02/14 Python
关于Python中定制类的比较运算实例
2019/12/19 Python
Python开发入门——迭代的基本使用
2020/09/03 Python
社区版pycharm创建django项目的方法(pycharm的newproject左侧没有项目选项)
2020/09/23 Python
Python类的继承super相关原理解析
2020/10/22 Python
size?瑞典:英国伦敦的球鞋精品店
2018/03/01 全球购物
俄罗斯EPL钻石珠宝店:ЭПЛ
2019/10/22 全球购物
酒店实习个人鉴定
2013/12/07 职场文书
五十岁生日宴会答谢词
2014/01/15 职场文书
学校联谊活动方案
2014/02/15 职场文书
上课打牌的检讨书
2014/02/15 职场文书
红头文件任命书范本
2014/06/05 职场文书
拯救大兵瑞恩观后感
2015/06/09 职场文书
公司要求试用期员工提交“述职报告”,该怎么写?
2019/07/17 职场文书
MySQL系列之十三 MySQL的复制
2021/07/02 MySQL
Python机器学习之决策树和随机森林
2021/07/15 Javascript