使用Python 比较mysql数据库中两个数据库的表结构,并导出差异部分的表结构

使用Python比较数据库表结构和表字段

       废话不多说,直接上代码

# -*- coding: UTF-8 -*- 
# @Time    : 2018/8/31 8:23
# @Author  : wuming.wang
# @Email   : [email protected]
# @File    : DiffDatabase.py
# @Software: PyCharm

import MySQLdb
import os
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

base_dir = os.path.abspath(os.path.dirname(__file__))


class Diff:
    def __init__(self):
        self.test_host = '192.168.**.***'
        self.test_user_name = '****'
        self.test_password = '****'
        self.test_port = '3306'
        self.test_dbname = '****'

        self.online_host = '192.***.**.**'
        self.online_user_name = '**'
        self.online_password = '***'
        self.online_port = '3306'
        self.online_dbname = '*****'

    def get_data(self, env, sql):
        if env == "test":
            conn = MySQLdb.connect(self.test_host, self.test_user_name, self.test_password, self.test_dbname,
                                   charset="utf8")
        else:
            conn = MySQLdb.connect(self.online_host, self.online_user_name, self.online_password, self.online_dbname,
                                   charset="utf8")

        cur = conn.cursor()
        cur.execute(sql)

        results = cur.fetchall()  # 搜取所有结果
        cur.close()
        conn.close()
        return results

    # 把返回的嵌套元素转换为列表
    def to_list(self, result):
        r_list = []
        for t in result:
            r_list.append(t[0])
        return r_list

    # test_table 里面有的 online_table没有
    def comp(self, test_table, online_table):
        ret = [i for i in test_table if i not in online_table]
        return ret

    # test_table online_table 都有的
    def both_list(self, L1, L2):
        both = [i for i in L1 if i in L2]
        return both

    def result(self, test, online):
        test_have = self.comp(test, online)
        online_have = self.comp(online, test)

        if len(test_have) + len(online_have) != 0:
            print "test环境有的table,online环境没有: \r\n"

            for i in test_have:
                print "  ", i

            print "\r"

            print "online环境有的table,test环境没有: \r\n"
            for i in online_have:
                print "  ", i

    def column_result(self, table_name, test, online):
        test_have = self.comp(test, online)
        online_have = self.comp(online, test)

        if len(test_have) + len(online_have) != 0:
            print "\r"
            print "    ", table_name, "表:test环境有的字段,online环境没有: \r\n"
            for i in test_have:
                print "         ", i
            print "\r"
            print "    ", table_name, "表:online环境有的字段,test环境没有: \r\n"
            for i in online_have:
                print "         ", i

    def export_table_structure(self, env, table_name):
        mysqldump_commad_params = {}
        mysqldump_commad_params['dumpcommad'] = 'mysqldump --no-data'
        if env == "test":
            mysqldump_commad_params['server'] = self.test_host
            mysqldump_commad_params['user'] = self.test_user_name
            mysqldump_commad_params['password'] = self.test_password
            mysqldump_commad_params['port'] = self.test_port
            mysqldump_commad_params['db'] = self.test_dbname
        else:
            mysqldump_commad_params['server'] = self.online_host
            mysqldump_commad_params['user'] = self.online_user_name
            mysqldump_commad_params['password'] = self.online_password
            mysqldump_commad_params['port'] = self.online_port
            mysqldump_commad_params['db'] = self.online_dbname

        file_name = """%s_have_%s.sql""" % (env, table_name)
        path = os.path.join(base_dir, 'sql', env, file_name)

        mysqldump_commad_sql = """%s -h%s -u%s -p%s -P%s %s %s > %s""" % (
            mysqldump_commad_params['dumpcommad'],
            mysqldump_commad_params['server'],
            mysqldump_commad_params['user'],
            mysqldump_commad_params['password'],
            mysqldump_commad_params['port'],
            mysqldump_commad_params['db'],
            table_name,
            path
        )

        # 必须切换到创建sql的文件夹下,才能执行命令!!!
        sql_file_path = os.path.join(base_dir, 'sql', env)
        if not os.path.exists(sql_file_path):
            os.makedirs(sql_file_path)

        os.chdir(sql_file_path)
        result = os.system(mysqldump_commad_sql)

        if result == 0:
            print """----------- 导出 %s 表结构成功!------------""" % (table_name)
        else:
            print """----------- 导出 %s 表结构失败!------------""" % (table_name)

            # print mysqldump_commad_sql

    def drop_more_comment(self,file_path):
        os.chdir()


if __name__ == '__main__':
    diff = Diff()

    test_table_list = diff.to_list(diff.get_data('test', "show tables"))
    online_table_list = diff.to_list(diff.get_data('online', "show tables"))
    both_have_t = diff.both_list(test_table_list, online_table_list)

    print "-----------------  比较两个database的table差异  begin --------------------------"
    print "\r"
    # 调用比较结果函数
    diff.result(test_table_list, online_table_list)
    print "\r"
    print "-----------------  比较两个database的table差异  end --------------------------"

    print "\r\n"
    print "共有表个数:", both_have_t.__len__()
    print "共有表:", both_have_t
    print "\r"

    print "-----------------  比较共有表的字段差异  begin --------------------------"
    print "\r"

    for i in range(0, len(both_have_t)):
        test_field_sql = "SELECT column_name FROM information_schema.columns WHERE Table_name= '%s' and table_schema = '%s'" % (
            both_have_t[i], diff.test_dbname)
        test_field = diff.to_list(diff.get_data("test", test_field_sql))
        online_field_sql = "SELECT column_name FROM information_schema.columns WHERE Table_name= '%s' and table_schema = '%s'" % (
            both_have_t[i], diff.online_dbname)
        online_field = diff.to_list(diff.get_data("online", online_field_sql))
        print i + 1, both_have_t[i]
        diff.column_result(both_have_t[i], test_field, online_field)
    print "\r"
    print "-----------------  比较共有表的字段差异  end --------------------------"

    print "\r\n"
    print "-----------------  导出 表结构 begin  -------------------------------"
    # 导出表结构sql
    print "-----------------  导出 test 环境有的表,而 online 环境没有的表 ----------"
    test_have = diff.comp(test_table_list, online_table_list)
    for table_name in test_have:
        diff.export_table_structure('test', table_name)
    print "\r\n"
    print "-----------------  导出 online 环境有的表,而 test 环境没有的表 ----------"
    online_have = diff.comp(online_table_list, test_table_list)
    for table_name in online_have:
        diff.export_table_structure('online', table_name)
    print "-----------------  导出 表结构 end  -------------------------------"

这里你需要设置你要比较的两个数据库的host,user,password等信息连接你的数据库

代码中主要有两个功能:

  1. 找出两个数据库的表的差集和具体表字段的差集
  2. 导出表的差集的表结构创建sql语句

可以在此基础上完善补充的功能:

  1. 去掉生成xx.sql的注解
  2. 导出相同表的表字段的差异sql部分

参考链接:

  1. https://www.cnblogs.com/aiyr/p/6735154.html
  2. https://blog.csdn.net/dm1314oooooooo/article/details/72818559
  3. https://www.linuxidc.com/Linux/2018-03/151390.htm

你可能感兴趣的:(mysql相关)