Mysql数据表结构同步Python实现

Mysql数据表结构同步Python实现


Python源码

#!/usr/bin/python

import MySQLdb
import configparser

class SchemaMysql:
	#初始化用户数据 isdrop参数为是否删除目标库多余的字段
	def __init__(self,src_info,des_info,isdrop):
		self.src_ip = src_info[0]
		self.src_db_user = src_info[1]
		self.src_db_pass = src_info[2]
		self.des_ip = des_info[0]
		self.des_db_user = des_info[1]
		self.des_db_pass = des_info[2]
		self.isDrop = isdrop


	#初始化不同的数据库
	def init(self,src_db,des_db):
		self.dbsrc = self.connect_db(self.src_ip,src_db,self.src_db_user,self.src_db_pass)
		self.dbdes = self.connect_db(self.des_ip,des_db,self.des_db_user,self.des_db_pass)
		self.cursorsrc = self.dbsrc.cursor()
		self.cursordes = self.dbdes.cursor()

	#手动关闭数据库
	def close_db(self):
		self.cursorsrc.close()
		self.cursordes.close()
		self.dbsrc.close()
		self.dbdes.close()

	#连接数据库
	def connect_db(self,ip,db,db_user,db_pass):
		db = MySQLdb.connect(ip,db_user,db_pass,db)
		return db

	#获取数据库中的表
	def getTable(self,cursor):
		cursor.execute("show tables")
		tablelist  = []
		for tb in cursor.fetchall():
			tablelist.append(tb[0])
		return tablelist

	#获取创表语句
	def getField(self,cursor,tb):
		sql = "show create table "+str(tb)
		cursor.execute(sql)
		return cursor.fetchone()

	#生成需要执行的sql语句
	def createSql(self,tb,mode,F):
		if mode == 'c':
			sql = "alter table " + str(tb) + " change " + F[0] + " " + F[0]
		elif mode == 'a':
			sql = "alter table " + str(tb) + " add " + F[0]
		elif mode == 'd':
			sql = "alter table " + str(tb) + " drop column " + F[0]
			return sql
		else:
			return None
		for d in range(1, len(F)):
			sql = sql + " " + F[d]
		return sql

	#检测两个数据表字段是否一样
	def checkField(self,tb,sqlSrc,sqlDes):
		runList = []
		srcList = sqlSrc[1].replace(",","").split("\n")[1:-1]#去除不需要的数据
		desList = sqlDes[1].replace(",","").split("\n")[1:-1]
		for i in srcList:
			srcF = i.split()
			for j in desList:
				desF = j.split()
				if srcF[0] == desF[0]:
					if len(srcF) == len(desF):
						for c in range(1,len(srcF)):
							if srcF[c] != desF[c]:
								runList.append(self.createSql(tb,"c",srcF))
					else:
						runList.append(self.createSql(tb, "c", srcF))
					break;
			else:
				runList.append(self.createSql(tb, "a", srcF))
		if self.isDrop:
			srcList =  [x.split()[0] for x in srcList]
			desList = [x.split()[0] for x in desList]
			for desI in desList:
				if desI not in srcList:
					runList.append(self.createSql(tb,"d",[desI]))
		return runList

	#执行 删除字段 增加字段 修改字段的sql语句
	def runExec(self,runlist):
		for run in runlist:
			print run
			self.cursordes.execute(run)

	#检测数据表是否一样如果没有则在目标主机上创建
	def checkTable(self,tbSrc,tbDes,cursrc,curdes):
		for tbA in tbSrc:
			dataSrc = self.getField(cursrc, tbA)
			if tbA in tbDes:
				runlist = self.checkField(tbA,dataSrc,self.getField(curdes,tbA))
				if not runlist is None:
					self.runExec(runlist)
			else:
				curdes.execute(dataSrc[1].replace("\n",""))

	#开始运行
	def run(self):
		print "Run"
		srctable = self.getTable(self.cursorsrc)
		destable = self.getTable(self.cursordes)
		self.checkTable(srctable,destable,self.cursorsrc,self.cursordes)

"""
获取config文件信息
包括  ip  用户  密码   表
"""
def getConfDBList():
	src_list = []
	des_list = []
	config = configparser.ConfigParser()
	config.read("config.cfg")
	src_list.append(config.get('SRC', 'ip'))
	src_list.append(config.get('SRC','user'))
	src_list.append(config.get("SRC",'pass'))
	src_list.append(config.get("SRC", 'db'))

	des_list.append(config.get('DES', 'ip'))
	des_list.append(config.get('DES', 'user'))
	des_list.append(config.get("DES", 'pass'))
	des_list.append(config.get("DES", 'db'))
	return [src_list,des_list]



if __name__ == '__main__':
	list = getConfDBList()
	src_info = ['172.16.0.55','root','root']
	des_info = ['172.16.0.55', 'root', 'root']
	src_db = list[0][3].split(",")
	des_db = list[1][3].split(",")
	print "Begin"
	schema = SchemaMysql(src_info,des_info,True)
	for i in range(len(src_db)):
		if src_db[i] and des_db[i]:
			schema.init(src_db[i],des_db[i])
			schema.run()
			schema.close_db()

config文件:
db必须需要逗号(,)分隔可以用多个库,SRC和DES中的db数量必须一样

[SRC]
ip=172.16.0.55
user=root
pass=root
db=te01,t001
[DES]
ip=172.16.0.55
user=root
pass=root
db=te02,t002

当然数据库很复杂这只是一个简单的例子,希望有帮助

你可能感兴趣的:(学习)