我在工作的時候,在測試環境下使用的資料庫跟生產環境的資料庫不一致,當我們的測試環境下的資料庫完成測試準備更新到生產環境上的資料庫時候,需要準備更新腳本,真是一不小心沒記下來就會忘了改了哪裡,哪裡添加了什麼,這個真是非常讓人頭疼。因此我就試著用Python來實現自動的生成更新腳本,以免我這爛記性,記不 ...
我在工作的時候,在測試環境下使用的資料庫跟生產環境的資料庫不一致,當我們的測試環境下的資料庫完成測試準備更新到生產環境上的資料庫時候,需要準備更新腳本,真是一不小心沒記下來就會忘了改了哪裡,哪裡添加了什麼,這個真是非常讓人頭疼。因此我就試著用Python來實現自動的生成更新腳本,以免我這爛記性,記不住事。
主要操作如下:
1.在原先 basedao.py 中添加如下方法,這樣舊能很方便的獲取資料庫的數據,為測試資料庫和生產資料庫做對比打下了基礎。
1 def select_database_struts(self): 2 ''' 3 查找當前連接配置中的資料庫結構以字典集合 4 ''' 5 sql = '''SELECT COLUMN_NAME, IS_NULLABLE, COLUMN_TYPE, COLUMN_KEY, COLUMN_COMMENT 6 FROM information_schema.`COLUMNS` 7 WHERE TABLE_SCHEMA="%s" AND TABLE_NAME="{0}" '''%(self.__database) 8 struts = {} 9 for k in self.__primaryKey_dict.keys(): 10 self.__cursor.execute(sql.format(k)) 11 results = self.__cursor.fetchall() 12 struts[k] = {} 13 for result in results: 14 struts[k][result[0]] = {} 15 struts[k][result[0]]["COLUMN_NAME"] = result[0] 16 struts[k][result[0]]["IS_NULLABLE"] = result[1] 17 struts[k][result[0]]["COLUMN_TYPE"] = result[2] 18 struts[k][result[0]]["COLUMN_KEY"] = result[3] 19 struts[k][result[0]]["COLUMN_COMMENT"] = result[4] 20 return self.__config, strutsView Code
2.編寫對比的Python腳本
1 ''' 2 資料庫遷移腳本, 目前支持一下幾種功能: 3 1.生成舊資料庫中沒有的資料庫表執行 SQL 腳本(支持是否帶表數據),生成的 SQL 腳本在 temp 目錄下(表名.sql)。 4 2.生成添加列 SQL 腳本,生成的 SQL 腳本統一放在 temp 目錄下的 depoyed.sql 中。 5 3.生成修改列屬性 SQL 腳本,生成的 SQL 腳本統一放在 temp 目錄下的 depoyed.sql 中。 6 4.生成刪除列 SQL 腳本,生成的 SQL 腳本統一放在 temp 目錄下的 depoyed.sql 中。 7 ''' 8 import json, os, sys 9 from basedao import BaseDao 10 11 temp_path = sys.path[0] + "/temp" 12 if not os.path.exists(temp_path): 13 os.mkdir(temp_path) 14 15 def main(old, new, has_data=False): 16 ''' 17 @old 舊資料庫(目標資料庫) 18 @new 最新的資料庫(源資料庫) 19 @has_data 是否生成結構+數據的sql腳本 20 ''' 21 clear_temp() # 先清理 temp 目錄 22 old_config, old_struts = old 23 new_config, new_struts = new 24 for new_table, new_fields in new_struts.items(): 25 if old_struts.get(new_table) is None: 26 gc_sql(new_config["user"], new_config["password"], new_config["database"], new_table, has_data) 27 else: 28 cmp_table(old_struts[new_table], new_struts[new_table], new_table) 29 30 def cmp_table(old, new, table): 31 ''' 32 對比表結構生成 sql 33 ''' 34 old_fields = old 35 new_fields = new 36 37 sql_add_column = "ALTER TABLE `{TABLE}` ADD COLUMN `{COLUMN_NAME}` {COLUMN_TYPE} COMMENT '{COLUMN_COMMENT}';\n" 38 sql_change_column = "ALTER TABLE `{TABLE}` CHANGE `{COLUMN_NAME}` `{COLUMN_NAME}` {COLUMN_TYPE} COMMENT '{COLUMN_COMMENT}';\n" 39 sql_del_column = "ALTER TABLE `{TABLE}` DROP {COLUMN_NAME};" 40 41 if old_fields != new_fields: 42 f = open(sys.path[0] + "/temp/deploy.sql", "a", encoding="utf8") 43 content = "" 44 for new_field, new_field_dict in new_fields.items(): 45 old_filed_dict = old_fields.get(new_field) 46 if old_filed_dict is None: 47 # 生成添加列 sql 48 content += sql_add_column.format(TABLE=table, **new_field_dict) 49 else: 50 # 生成修改列 sql 51 if old_filed_dict != new_field_dict: 52 content += sql_change_column.format(TABLE=table, **new_field_dict) 53 pass 54 # 生成刪除列 sql 55 for old_field, old_field_dict in old_fields.items(): 56 if new_fields.get(old_field) is None: 57 content += sql_del_column.format(TABLE=table, COLUMN_NAME=old_field) 58 59 f.write(content) 60 f.close() 61 62 def gc_sql(user, pwd, db, table, has_data): 63 ''' 64 生成 sql 文件 65 ''' 66 if has_data: 67 sys_order = "mysqldump -u%s -p%s %s %s > %s/%s.sql"%(user, pwd, db, table, temp_path, table) 68 else: 69 sys_order = "mysqldump -u%s -p%s -d %s %s > %s/%s.sql"%(user, pwd, db, table, temp_path, table) 70 os.system(sys_order) 71 72 def clear_temp(): 73 ''' 74 每次執行的時候調用這個,先清理下temp目錄下麵的舊文件 75 ''' 76 if os.path.exists(temp_path): 77 files = os.listdir(temp_path) 78 for file in files: 79 f = os.path.join(temp_path, file) 80 if os.path.isfile(f): 81 os.remove(f) 82 print("臨時文件目錄清理完成") 83 84 if __name__ == "__main__": 85 test1_config = { 86 "user" : "root", 87 "password" : "root", 88 "database" : "test1", 89 } 90 test2_config = { 91 "user" : "root", 92 "password" : "root", 93 "database" : "test2", 94 } 95 96 test1_dao = BaseDao(**test1_config) 97 test1_struts = test1_dao.select_database_struts() 98 99 test2_dao = BaseDao(**test2_config) 100 test2_struts = test2_dao.select_database_struts() 101 102 main(test2_struts, test1_struts)View Code
目前只支持了4種SQL腳本的生成。
如果有感興趣一起學習、討論Python的可以加QQ群:626787819,有啥意見或者建議的可以發我郵箱:[email protected]。