> 数据库 > MySQL >

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

(责任编辑:IT)