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中字典的键的使用
Aug 19 Python
Python实现简单的文件传输与MySQL备份的脚本分享
Jan 03 Python
python中os模块详解
Oct 14 Python
python实现pdf转换成word/txt纯文本文件
Jun 07 Python
对pandas数据判断是否为NaN值的方法详解
Nov 06 Python
Django组件之cookie与session的使用方法
Jan 10 Python
python 调用钉钉机器人的方法
Feb 20 Python
详解python爬虫系列之初识爬虫
Apr 06 Python
python实现代码统计程序
Sep 19 Python
python datetime处理时间小结
Apr 16 Python
Python基于pyjnius库实现访问java类
Jul 31 Python
Python爬虫实战之爬取携程评论
Jun 02 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实现伪静态方法汇总
2016/01/13 PHP
WordPress过滤垃圾评论的几种主要方法小结
2016/07/11 PHP
javascript检查日期格式的函数[比较全]
2008/10/17 Javascript
JavaScript 脚本将当地时间转换成其它时区
2009/03/19 Javascript
JavaScript 使用技巧精萃(.net html
2009/04/25 Javascript
Javascript Cookie读写删除操作的函数
2010/03/02 Javascript
node.js中的fs.linkSync方法使用说明
2014/12/15 Javascript
JavaScript中日常收集常见的10种错误(推荐)
2017/01/08 Javascript
Bootstrap3 多个模态对话框无法显示的解决方案
2017/02/23 Javascript
基于bootstrap实现bootstrap中文网巨幕效果
2017/05/02 Javascript
node.js连接MongoDB数据库的2种方法教程
2017/05/17 Javascript
微信小程序实现流程进度的图样式功能
2018/01/16 Javascript
vue+express 构建后台管理系统的示例代码
2018/07/19 Javascript
vue mounted 调用两次的完美解决办法
2018/10/29 Javascript
JS获取当前时间的实例代码(昨天、今天、明天)
2018/11/13 Javascript
重置Redux的状态数据的方法实现
2019/11/18 Javascript
mpvue微信小程序开发之实现一个弹幕评论
2019/11/24 Javascript
JavaScript实现拖拽功能
2020/02/11 Javascript
vue实现计算器功能
2020/02/22 Javascript
Python自然语言处理 NLTK 库用法入门教程【经典】
2018/06/26 Python
[原创]Python入门教程3. 列表基本操作【定义、运算、常用函数】
2018/10/30 Python
带你认识Django
2019/01/15 Python
Django  ORM 练习题及答案
2019/07/19 Python
python实现简单日志记录库glog的使用
2019/12/13 Python
Keras实现支持masking的Flatten层代码
2020/06/16 Python
解决pytorch多GPU训练保存的模型,在单GPU环境下加载出错问题
2020/06/23 Python
Python爬虫逆向分析某云音乐加密参数的实例分析
2020/12/04 Python
Sam’s Club山姆会员商店:沃尔玛旗下高端会员制商店
2017/01/16 全球购物
大二法英学生职业生涯规划范文
2014/02/27 职场文书
师德师风整改措施
2014/10/24 职场文书
六一文艺汇演开幕词
2015/01/29 职场文书
综合管理员岗位职责
2015/02/11 职场文书
财务会计求职信范文
2015/03/20 职场文书
作文之亲情600字
2019/09/23 职场文书
Smart 2 车辆代号 HC11 全新谍照曝光
2022/04/21 数码科技
vue-treeselect的基本用法以及解决点击无法出现拉下菜单
2022/04/30 Vue.js