我在工做的時候,在測試環境下使用的數據庫跟生產環境的數據庫不一致,當咱們的測試環境下的數據庫完成測試準備更新到生產環境上的數據庫時候,須要準備更新腳本,真是一不當心沒記下來就會忘了改了哪裏,哪裏添加了什麼,這個真是很是讓人頭疼。所以我就試着用Python來實現自動的生成更新腳本,以避免我這爛記性,記不住事。mysql
主要操做以下:sql
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, struts
2.編寫對比的Python腳本json
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 1.系統必須配置 mysql 的環境變量,確保 mysqldump 指令能執行。 9 2.數據庫表必須帶有主鍵。 10 ''' 11 import json, os, sys 12 from basedao import BaseDao 13 14 temp_path = sys.path[0] + "/temp" 15 if not os.path.exists(temp_path): 16 os.mkdir(temp_path) 17 18 def main(old, new, has_data=False): 19 ''' 20 @old 舊數據庫(目標數據庫) 21 @new 最新的數據庫(源數據庫) 22 @has_data 是否生成結構+數據的sql腳本 23 ''' 24 clear_temp() # 先清理 temp 目錄 25 old_config, old_struts = old 26 new_config, new_struts = new 27 for new_table, new_fields in new_struts.items(): 28 if old_struts.get(new_table) is None: 29 gc_sql(new_config["user"], new_config["password"], new_config["database"], new_table, has_data) 30 else: 31 cmp_table(old_struts[new_table], new_struts[new_table], new_table) 32 33 def cmp_table(old, new, table): 34 ''' 35 對比表結構生成 sql 36 ''' 37 old_fields = old 38 new_fields = new 39 40 sql_add_column = "ALTER TABLE `{TABLE}` ADD COLUMN `{COLUMN_NAME}` {COLUMN_TYPE} COMMENT '{COLUMN_COMMENT}';\n" 41 sql_change_column = "ALTER TABLE `{TABLE}` CHANGE `{COLUMN_NAME}` `{COLUMN_NAME}` {COLUMN_TYPE} COMMENT '{COLUMN_COMMENT}';\n" 42 sql_del_column = "ALTER TABLE `{TABLE}` DROP {COLUMN_NAME};" 43 44 if old_fields != new_fields: 45 f = open(sys.path[0] + "/temp/deploy.sql", "a", encoding="utf8") 46 content = "" 47 for new_field, new_field_dict in new_fields.items(): 48 old_filed_dict = old_fields.get(new_field) 49 if old_filed_dict is None: 50 # 生成添加列 sql 51 content += sql_add_column.format(TABLE=table, **new_field_dict) 52 else: 53 # 生成修改列 sql 54 if old_filed_dict != new_field_dict: 55 content += sql_change_column.format(TABLE=table, **new_field_dict) 56 pass 57 # 生成刪除列 sql 58 for old_field, old_field_dict in old_fields.items(): 59 if new_fields.get(old_field) is None: 60 content += sql_del_column.format(TABLE=table, COLUMN_NAME=old_field) 61 62 f.write(content) 63 f.close() 64 65 def gc_sql(user, pwd, db, table, has_data): 66 ''' 67 生成 sql 文件 68 ''' 69 if has_data: 70 sys_order = "mysqldump -u%s -p%s %s %s > %s/%s.sql"%(user, pwd, db, table, temp_path, table) 71 else: 72 sys_order = "mysqldump -u%s -p%s -d %s %s > %s/%s.sql"%(user, pwd, db, table, temp_path, table) 73 try: 74 res = os.system(sys_order) 75 if res == 0: 76 print("生成%s表sql文件。"%table) 77 except Exception as e: 78 print(e) 79 80 def clear_temp(): 81 ''' 82 每次執行的時候調用這個,先清理下temp目錄下面的舊文件 83 ''' 84 if os.path.exists(temp_path): 85 files = os.listdir(temp_path) 86 for file in files: 87 f = os.path.join(temp_path, file) 88 if os.path.isfile(f): 89 os.remove(f) 90 print("臨時文件目錄清理完成") 91 92 if __name__ == "__main__": 93 test1_config = { 94 "user" : "root", 95 "password" : "root", 96 "database" : "test1", 97 } 98 test2_config = { 99 "user" : "root", 100 "password" : "root", 101 "database" : "test2", 102 } 103 104 test1_dao = BaseDao(**test1_config) 105 test1_struts = test1_dao.select_database_struts() 106 107 test2_dao = BaseDao(**test2_config) 108 test2_struts = test2_dao.select_database_struts() 109 110 main(test2_struts, test1_struts)
目前只支持了4種SQL腳本的生成。ide
若是有感興趣一塊兒學習、討論Python的能夠加QQ羣:626787819,有啥意見或者建議的能夠發我郵箱:410093793@qq.com。學習