【原創】如引用,請注明出處,謝謝!
總公司的某數據以文件形式存放在FTP服務器上,現將其移植到我本地的SQL服務器。
我已有連接pyodbc
1 import pyodbc
2 import pandas as pd 3 from ftplib import FTP 4 import sqlalchemy 5 6 ip='XXX.XXX.XXX.XXX' 7 port=21 8 username='XXX' 9 password='XXXXX' 10 ftp=FTP() 11 ftp.connect(ip,port) 12 ftp.login(username,password) 13 ftp.cwd('./cds') #進入到我的子目錄 14 buffersize=1024 15 filename='3407_20200101_20200607.unl' #當然,可動態獲取文件名 16 try: 17 with open(filename,'rb') as fp: 18 ftp.retrbinary('RETR %s'%os.path.basename(filname), fp.write,buffersize) 19 except: 20 pass 21 ftp.quit() 22 #由於informix生成的unl文件為cp936編碼,pandas 讀取時會對有些漢字報錯,所以轉為utf-8 23 with open(filename,'r',encoding='cp936') as fp1,open('_temp.txt','w',encoding='utf-8') as fp2: 24 fp2.write(fp1.read()) 25 26 #本地為SQLServer+pyodbc,並已經建立了ODBC-DSN ,下面為關鍵代碼 27 engine = sqlalchemy.create_engine("mssql+pyodbc://<username>:<password>@<dsnname>") 28 29 #對_tmp.txt 文件讀取時,要注意純數字的(編碼、ID等等)格式轉換(可直接轉換成object), 30 31 #否則Pandas會自動轉換為float或bigint 32 33 df=pd.read_csv('_temp.txt',sep='|',header=None,dtype={5:object,7:object}) 34 35 #(我的數據文件無列名,第5和7列為數值型文本,從第0列開始) 36 #最后一列為空,drop掉 37 df=df.drop(28,axis=1) 38 #增加列名,title為列名list 39 title=['','','',...] 40 df.columns=title 41 42 # 寫pandas 的 DataFrame 到SQLServer的一個表 43 df.to_sql("table_name", engine,index=False) 44 45 #這樣建立的表實質上數據類型與我的預期是不符的 46 #通過先建立符合預期的結構表來改變類型 47 with engine.connect() as con: 48 con.execute("IF OBJECT_ID('table_name') IS NOT NULL TRUNCATE TABLE table_name ELSE SELECT * INTO FROM table_name_bak WHERE 1=0 ")
49 df.to_sql("table_name", engine,index=False,if_exists='append')
50 #至此,完美!