目录结构:
运行db2csv,通过读取配置,将数据从数据库写入csv文件,存储到out目录下,并上传到FTP服务器上,另一台服务器读取FTP,将csv文件读取到in目录,然后运行csv2db.py 将数据存入数据库指定表。
config.py 里面的 tables 用作导出数据,csvs 用作导入数据:
# -*- coding:utf-8 -*- tables=[ { 'table':"wan_day", 'sql':"select * from wan_day limit 10", 'host':"Server=1.1.1.1;Port=3306;Database=dbdbdb;Uid=root;Pwd=123456", 'type':"mysql"#mysql 数据库 }, { 'table':"v_e_fad_week_data", 'sql':"select top 10 * from v_e_fad_week_data ", 'host':"Server=1.1.1.1;Database=dbdbdb ;Uid=root;Pwd=123456", 'type':"mssql"#sql server数据库 } ] csvs=[{ 'fileName':"wan_day.csv", 'sql':"replace into test_wan_day values ", 'host':"Server=1.1.1.2;Port=3306;Database=test;Uid=root;Pwd=123456", 'type':"mysql" }]
db2csv.py 用来读取上述tables,然后从数据库导出数据到csv。
#!/usr/bin/env python # -*- coding:utf-8 -*- import csv import config import dbEngine for t in config.tables: if(t['type'] == "mysql"): mysqlE = dbEngine.mysqlEngine(t['host']) mysqlE.Sql2CSV(t['sql'],t['table']) elif(t['type'] == "mssql"): mssqlE = dbEngine.mssqlEngine(t['host']) mssqlE.Sql2CSV(t['sql'],t['table'])
csv2db.py ,将in 目录下的 csv 存入到数据库。
#!/usr/bin/env python # -*- coding:utf-8 -*- import csv import config import dbEngine import re import os def getConf(fileName): for c in config.csvs: if(re.match(c['fileName'],fileName)): return c return None for root,dirs,files in os.walk('in'): for f in files: c = getConf(f) if(c): mysqlE = dbEngine.mysqlEngine(c["host"]) mysqlE.CSV2DB(os.path.join(root,f),c)
下面开始核心的方法了。 dbEngine.py 对数据库的操作都在这里,目前针对mysql ,sqlserver的操作,可以扩充其它数据库:
# -*- coding:utf-8 -*- import MySQLdb import pymssql import csv import os import stat import shutil import codecs class mysqlEngine: def __init__(self,connectionString): conns = connectionString.split(';') myList = [] for con in conns: myList.append((con.split('=')[0],con.split('=')[1])) myDic = dict(myList) self.host = 'localhost' self.port = 3306 if(myDic.has_key('Port')): self.port = int(myDic['Port']) if(myDic.has_key('Server')): self.host = myDic['Server'] self.user = myDic['Uid'] self.password = myDic['Pwd'] self.database = myDic['Database'] def Sql2CSV(self,sql,table): conn = MySQLdb.connect(host=self.host,port = self.port,user=self.user,passwd=self.password,db=self.database) cur = conn.cursor() _data=cur.execute(sql) data = cur.fetchmany(_data) if(not os.path.exists('out')): os.mkdir("out") if(os.path.exists('out/'+table+'.csv')): os.chmod('out/'+table+'.csv',stat.S_IWRITE) os.remove('out/'+table+'.csv') with open('./out/'+table+'.csv', 'wb') as csvfile: spamwriter = csv.writer(csvfile,dialect='excel') for d in data: spamwriter.writerow(list(d)) print '--success to write '+ table+'.csv' def CSV2DB(self,csvFile,c): conn = MySQLdb.connect(host=self.host,port = self.port,user=self.user,passwd=self.password,db=self.database) cur = conn.cursor() sql = c["sql"] col_count = 0 reader = csv.reader(file(csvFile, 'rb')) data = [] for line in reader: data.append(tuple(line)) if(col_count == 0): col_count = len(line) sql += ' (' + ("%s,"*col_count).strip(",") + ")" if(len(data) == 1000): try: cur.executemany(sql,data) except Exception,e: print e data=[] if(len(data) >0 ): try: cur.executemany(sql,data) except Exception,e: print e cur.close() conn.commit() conn.close() print "--insert file "+ csvFile + ' to '+ self.database class mssqlEngine: def __init__(self,connectionString): conns = connectionString.split(';') myList = [] for con in conns: myList.append((con.split('=')[0],con.split('=')[1])) myDic = dict(myList) self.host = 'localhost' self.port = 1433 if(myDic.has_key('Port')): self.port = int(myDic['Port']) if(myDic.has_key('Server')): self.host = myDic['Server'] self.user = myDic['Uid'] self.password = myDic['Pwd'] self.database = myDic['Database'] def Sql2CSV(self,sql,table): conn = pymssql.connect(host=self.host,port = self.port,user=self.user,password=self.password,database=self.database) cur = conn.cursor() _data=cur.execute(sql) data = cur.fetchall() if(not os.path.exists('out')): os.mkdir("out") if(os.path.exists('out/'+table+'.csv')): os.chmod('out/'+table+'.csv',stat.S_IWRITE) os.remove('out/'+table+'.csv') with open('./out/'+table+'.csv', 'wb') as csvfile: spamwriter = csv.writer(csvfile,dialect='excel') for d in data: l=[] for i in d: if(type(i) is unicode): i = i.encode('raw_unicode_escape') l.append(i) spamwriter.writerow(l) print '--success to write '+ table+'.csv'
完成。 这个工具完整copy到两台服务器,通过修改config 以及根据需要运行db2csv或者csv2db即可。FTP的操作下篇。