|
在大型項目中,經(jīng)常需要執(zhí)行數(shù)據(jù)庫腳本,有些腳本特別大。如幾十兆的sql文件,盲目地執(zhí)行可能會導(dǎo)致很多的問題。如: 1)進(jìn)度不可控,時間難把握。 2)腳本中間出現(xiàn)差錯,導(dǎo)致后續(xù)報錯,甚至跑錯語句。 3)有重啟工程,意外宕機,就會中斷執(zhí)行任務(wù)。 4)不利于檢查和完善。 如果能夠?qū)⑦@么大sql文件進(jìn)行切割,分成多個小任務(wù),每天按照計劃跑,以上問題基本可以得到解決。 安老師通過實戰(zhàn)總結(jié)了一些經(jīng)驗,下面就開始為大家介紹如何精準(zhǔn)切割文件。 大綱 1. 使用os.path模塊和open模塊 2. 切割文件演示 01 使用os.path模塊和open模塊 1. os.path模塊 ![]() 2. open模塊 ![]() 02 切割文件演示 1. 演示場景 本次默認(rèn)Windows切割文件,演示的圖片如下 1.1 原文件 文件路徑 F:\python\py自動化運維\公眾號\5 python切割文件\test.sql 文件首部(圖一,總1416行,此sql腳本為數(shù)據(jù)庫劈2016年的月分區(qū)。) ![]() 文件尾部(圖二) ![]() 2. 切割文件代碼 1import os 2import time 3 4def mkSubFile(bufferline, filenamepath, num): 5 [desfilename, typename] = os.path.splitext(filenamepath) 6 nfilename = desfilename + '_' + str(num) + typename 7 print('make file: %s' % nfilename) 8 scriptfile = open(nfilename, 'w') 9 try:10 scriptfile.writelines(bufferline)11 return num + 112 finally:13 scriptfile.close()1415def splitByLineCount(filenamepath, count):16 filename = open(filenamepath, 'r')17 try:18 bufferline = []19 num = 120 filename.seek(0)21 for line in filename:22 bufferline.append(line)23 if len(bufferline) == count and num >=1 :24 num = mkSubFile(bufferline, filenamepath, num)25 bufferline = []26 if len(bufferline) != count and num >=1 :27 num = mkSubFile(bufferline, filenamepath, num)28 finally:29 filename.close()3031if __name__ == '__main__':32 begin = time.time()33 filenamepath = r'F:\python\py自動化運維\公眾號\5 python切割文件\test.sql'34 splitByLineCount(filenamepath, 500)35 end = time.time()36 print('time is %d seconds ' % (end - begin)) 2.1 重點代碼詳解 1)執(zhí)行流 begin = time.time() 開始切割時間 filenamepath 需要被切割的文件路徑 splitByLineCount(filenamepath, 500) 切割函數(shù)(被切割文件路徑,滿500行切割文件) end = time.time() 結(jié)束切割時間 1)第5行 os.path.splitext 拆分原文件路徑,得到文件名和擴展名 2)第6行 標(biāo)記切割第幾個文件 3)第8行 scriptfile = open(nfilename, 'w') 開始寫入文件 4)第11行 return num + 1 返回num值,下次切割文件為num+1值 5)第18行 bufferline = [],新建數(shù)組,記錄讀取行數(shù)值 6)第19行 num = 1,第一個切割文件 7)第20行 filename.seek(0),確保指針在第一行的起始位置 8)第21行 for line in filename 讀取文件的每一行 9)第22行 bufferline.append(line) bufferline數(shù)組添加讀取的每一行數(shù)據(jù) 10)第23行 if len(bufferline) == count and num >=1,如果滿足count值,就切割一個文件出來,并把bufferline數(shù)組清空,下次再重新開始記錄 11)第24行 mkSubFile函數(shù),滿足count值,切割文件 12)第26 行 bufferline不滿足count值,退出For循環(huán),此時bufferline有存數(shù)據(jù) 13)第27行 mkSubFile函數(shù),文件剩下的行數(shù),不滿足count值,切割文件 2.2 切割文件優(yōu)缺點 優(yōu)點:短時間內(nèi)精準(zhǔn)切割文件。 缺點:不能自動生成后臺可執(zhí)行腳本,需要手工'添油加醋',仍然需要大量時間。 2.3 執(zhí)行演示 由圖可見,原文件不到1s就被切割成3個文件,請老鐵們放心,此時原文件還是存在的。根據(jù)安老師的實戰(zhàn)經(jīng)驗,10萬行的腳本,精準(zhǔn)切割5000行,也不需要1分鐘,是不是非常高效呢? ![]() 第一個腳本test_1.sql和原文件的開頭一樣,這是成功切割的第一步。 ![]() 第一個腳本test_1.sql的尾部。 ![]() 第二個腳本test_2.sql的文件內(nèi)容首部成功銜接test_1.sql的尾部。 ![]() 第三個腳本test_3.sql的文件行數(shù)只有416行,根據(jù)推算,這是正確的!整個切割過程,數(shù)據(jù)和行數(shù)并沒有丟失,這很成功! ![]() |
|
|