標籤:des style blog http io ar color os 使用
上次的那幾個指令碼這次全部整合到了一起,而且後面發現了一個可以使用的ODBC包,於是這次採用的方式就很簡單了,直接通過ODBC將InterBase資料庫中的資料全部取出來之後通過Python的sqlalchemyORM架構直接連接遠端MySQL資料庫,之後便可以方便的傳遞資料了,當然,作為我的終極完善版本,自動模式和手動模式是少不了的了,在自動模式中將自動檢查InterBase資料庫是否存在,如果不存在則自動restore,然後自己建立InterBase的資料來源,之後便可以取出資料了,下面是流程圖。
那麼下面就是講解代碼的時候咯~
這次的這個腳步主要分為三個函數,main函數,odbc函數和restore函數,由於手動模式包含在自動模式中,那麼我就只介紹自動模式了。
我在指令碼中定義了一個字典用來儲存指令碼的配置資訊,使用者可以在字典中定義自己需要的功能和資料庫資訊等。
#定義一個配置字典,將所需的參數添加在字典中方便改動setting = {#設定啟動模式‘operate_type‘:OPERATE_AUTO_RESTORE,#備份檔案的地址‘gbk_path‘:‘C:\\XXX\\DB.gbk‘,#需要恢複的InterBase資料庫地址‘gdb_path‘:‘C:\\\XXX\\\DB.GDB‘,#設定需要串連的MySQL資料庫的使用者名稱,密碼,ip地址和連接埠號碼‘username‘:‘root‘, ‘password‘:‘root‘, ‘port‘:‘3306‘, ‘dbname‘:‘test‘, ‘localhost‘:‘127.0.0.1‘,#設定需要串連的ODBC的名字以及使用者名稱和密碼‘DSN‘:‘XXX‘,‘UID‘:‘SYSDBA‘,‘PWD‘:‘masterkey‘}
在指令碼啟動的時候就通過判斷來確定使用者是以何種模式進行的指令碼,緊接著運行適合的指令碼
if __name__ == ‘__main__‘: #判斷啟動模式是自動模式還是手動模式 if setting[‘operate_type‘]==OPERATE_AUTO_RESTORE: #檢查資料庫是否存在,如果存在將跳過restore if os.path.isfile(‘C:\\XXX\\DB.GDB‘) == False: restore() odbc() main() else: print ‘The database has been exist, will skip restore...‘ odbc() main() elif setting[‘operate_type‘]==OPERATE_AUTO_EXPORT: main()
當Python判斷InterBase資料庫不存在之後便執行restore來恢複資料庫
#自動模式中恢複資料庫的方法def restore(): os.system(‘gbak -c -user "sysdba" -password "masterkey" "‘+setting[‘gbk_path‘]+‘" "127.0.0.1:‘+setting[‘gdb_path‘]+‘"‘)
之後便是自動建立InterBase的ODBC資料來源了,當然首先要安裝InterBase的驅動了,網上有很多,我就不一一的列出了,由於是在windows平台上啟動並執行,所以很方便的就可以使用添加註冊表的形式將需要的資料來源添加進系統中了,當然,既然是通過註冊表匯入的那麼就必然會產生出一個註冊表檔案了,我將它預設的產生在C盤的根目錄,然後在匯入完成之後再刪除掉,這樣就在指令碼運行完之後也不會產生垃圾了。
#下面這個字串建立了所需要的ODBC資料來源,並將資料來源中的資料庫地址改為restore輸出的資料庫地址def odbc(): odbcreg = ‘‘‘Windows Registry Editor Version 5.00[HKEY_CURRENT_USER\Software\ODBC\ODBC.INI][HKEY_CURRENT_USER\Software\ODBC\ODBC.INI\kmk]"Driver"="C:\\\WINDOWS\\\system32\\\OdbcFb32.dll""Description"="""Dbname"="‘‘‘+setting[‘gdb_path‘]+‘‘‘""Client"="""User"="SYSDBA""Role"="""CharacterSet"="NONE""JdbcDriver"="IscDbc""ReadOnly"="N""NoWait"="N""LockTimeoutWaitTransactions"="""Dialect"="3""QuotedIdentifier"="Y""SensitiveIdentifier"="N""AutoQuotedIdentifier"="N""UseSchemaIdentifier"="0""SafeThread"="Y""Password"="DKEBFJENHFCOBHGHLAIMNAAFICELEAEGDNMFNOGALAMHBBGCHFADNKCBPPGMANOGIEKENIOPHDIPBIECPLLLCBIKEJKMJLPLIB"[HKEY_CURRENT_USER\Software\ODBC\ODBC.INI\ODBC Data Sources]"kmk"="Firebird/InterBase(r) driver" ‘‘‘ #在C盤根目錄下建立一個臨時的註冊表檔案用來將建立的資料來源匯入 fp = open(‘C:\\db007.reg‘,‘w‘) try: fp.write(odbcreg) except Exception,e: print e finally: fp.close() #執行產生的資料來源註冊表檔案 os.system(‘regedit /s C:\\db007.reg‘) #將臨時產生的註冊表檔案刪除 os.remove(‘C:\\db007.reg‘)
緊接著就是我們最關鍵的main函數咯~
當然了,這次和上次一樣使用的是Python中SQLAlchemyORM的架構了,所以第一件事便是串連資料庫,獲得Session了,不過再次之前還是要先構建類與表的映射關係了。
#建立一個基類Base = declarative_base()#定義一個User類與資料庫進行映射class User(Base): __tablename__ = ‘User‘ NAME= Column(Integer, primary_key=True) PASSWORD= Column(Integer) .......
然後在獲得Session之後便可以串連ODBC了,通過SQL語句將InterBase資料庫中的資料取出來。
#建立資料庫的串連 mysql_db = create_engine( ‘mysql://‘+setting[‘username‘]+‘:‘+setting[‘password‘]+‘@‘+setting[‘localhost‘]+ ‘:‘+setting[‘port‘]+‘/‘+setting[‘dbname‘],echo=False) Base.metadata.bind=mysql_db Base.metadata.create_all(mysql_db) #建立一個Session Session = sessionmaker(bind=mysql_db) session = Session() #pdb.set_trace() #建立與ODBC資料來源的串連 conn = pyodbc.connect(‘DSN=‘+setting[‘DSN‘]+‘;UID=‘+setting[‘UID‘]+‘;PWD=‘+setting[‘PWD‘]+‘‘) curs = conn.cursor() #通過SQL語句得到一個對象 dbf = curs.execute(‘select *from User‘)
下面就是自動模式與手動模式都必須進過的步驟了~通過迴圈將資料提交到MySQL中,當然,為了防止資料庫中已經有了資料,那麼就在添加之前檢查資料庫中是否有這個資料,如果有的話便跳過這次添加,繼續後面的步驟。然後在每1000次添加之後提交一次資料,以減輕資料的壓力,最後在迴圈外將除以1000的餘數統一再存入資料庫中。
#迴圈的將對象中的資料儲存到User類中 commint = 0 for line1 in dbf: #檢查資料庫中的資料是否有資料,如果沒有則加入資料 exist = session.query(User).filter(User.ID == line1.ID,User.NAME == line1.NAME).count() if exist>0: continue u = User() u.NAME = line1.NAME ...... u.PASSWORD = line1.PASSWORD session.add(u) commint = commint+1 #當迴圈了1000次之後進行一次提交 if commint%1000==0: try: session.commit() #pdb.set_trace() session.flush() except: print ‘error‘ session.rollback() #將剩餘的資料進行提交 try: session.commit() session.flush() except Exception , e: print e session.rollback() session.close()
至此,這個是用ODBC讀取資料然後在儲存在MySQL的Python指令碼就寫完了,斷斷續續進過了一周多的日子,我實習的第一個正式任務也算是完美收官了,曾經在校園裡學了幾年的J2EE,萬萬沒想到最後卻來做了Python和資料庫。。。。不知道後面的日子裡還有什麼樣奇怪的任務等著我~~當然!我依舊不會放棄web的!加班狗努力!
Python資料庫遷移指令碼(終極版)