Python如何查看两个数据库的同名表的字段名差异

作者:XerCis 时间:2024-01-25 04:37:57 

查看两个数据库的同名表的字段名差异

问题描述

开发过程中有多个测试环境,测试环境 A 加了字段,测试环境 B 忘了加,字段名对不上,同一项目就报错了

Python如何查看两个数据库的同名表的字段名差异

CREATE DATABASE `a` CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';
CREATE DATABASE `b` CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';

USE `a`;
CREATE TABLE `student` (
 `id` int(11) AUTO_INCREMENT,
 `class_id` int(11) DEFAULT NULL,
 `name` varchar(255),
 `birthday` date,
 `chinese` int(11),
 `math` int(11),
 `english` int(11),
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

USE `b`;
CREATE TABLE `student` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `class_id` int(11) DEFAULT NULL,
 `name` varchar(255) DEFAULT NULL,
 `birthday` date DEFAULT NULL,
 `gender` tinyint(4) DEFAULT NULL,
 `chinese` int(11) DEFAULT NULL,
 `math` int(11) DEFAULT NULL,
 `english` int(11) DEFAULT NULL,
 `physics` int(11) DEFAULT NULL,
 `chemistry` int(11) DEFAULT NULL,
 `biology` int(11) DEFAULT NULL,
 PRIMARY KEY (`id`),
 KEY `idx_class_id` (`class_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

解决方案

安装

pip install SQLAlchemy
pip install pymysql

代码

from collections import defaultdict

import sqlalchemy
from sqlalchemy.engine.reflection import Inspector

def get_table_column_map(inspector: Inspector):
   """获取数据库中所有表对应的字段"""
   table_column_map = defaultdict(set)
   table_names = inspector.get_table_names()
   for table_name in table_names:
       columns = inspector.get_columns(table_name)  # 字段信息
       # indexes = inspect.get_indexes(table_name)  # 索引信息
       for column in columns:
           table_column_map[table_name].add(column['name'])
   return table_column_map

def compare_table_column_difference(a, b):
   """对比同名表字段的差异"""
   table_names = set(a) & set(b)  # 同名表
   for table_name in table_names:
       columns_a = a[table_name]
       columns_b = b[table_name]
       difference = columns_a ^ columns_b
       if difference:
           print(table_name, difference)

engine = sqlalchemy.create_engine('mysql+pymysql://root:123456@127.0.0.1:3306/a')
engine1 = sqlalchemy.create_engine('mysql+pymysql://root:123456@127.0.0.1:3306/b')
inspector = sqlalchemy.inspect(engine)
inspector1 = sqlalchemy.inspect(engine1)
table_column_map = get_table_column_map(inspector)
table_column_map1 = get_table_column_map(inspector1)
compare_table_column_difference(table_column_map, table_column_map1)
# student {'gender', 'chemistry', 'physics', 'biology'}

mysql-utilities

也可以使用专门的工具——mysql-utilities 中的 mysqldiff

文档

mysqldiff --help

命令

mysqldiff --server1=user:pass@host:port --server2=user:pass@host:port db1.object1:db2.object1

例子

mysqldiff --server1=root:123456@127.0.0.1:3306 --server2=root:123456@127.0.0.1:3306 a.student:b.student

效果


Python如何查看两个数据库的同名表的字段名差异

--- a.student
+++ b.student
@@ -3,8 +3,13 @@
  `class_id` int(11) DEFAULT NULL,
  `name` varchar(255) DEFAULT NULL,
  `birthday` date DEFAULT NULL,
+  `gender` tinyint(4) DEFAULT NULL,
  `chinese` int(11) DEFAULT NULL,
  `math` int(11) DEFAULT NULL,
  `english` int(11) DEFAULT NULL,
-  PRIMARY KEY (`id`)
+  `physics` int(11) DEFAULT NULL,
+  `chemistry` int(11) DEFAULT NULL,
+  `biology` int(11) DEFAULT NULL,
+  PRIMARY KEY (`id`),
+  KEY `idx_class_id` (`class_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8

优点:比较内容更详尽

缺点:无法批量,要自己指定比较对象(稍微改写即可克服)

Python数据库之间差异对比
 

此脚本用于两个数据库之间的表、列、栏位、索引的差异对比。

cat oracle_diff.py
#!/home/dba/.pyenv/versions/3.5.2/bin/python
#coding=utf-8
import cx_Oracle
import time
import difflib
import os
v_host=os.popen('echo $HOSTNAME')
class Oracle_Status_Output():
    def __init__(self,username,password,tns):
        try:
            self.db = cx_Oracle.connect(username,password,tns)
            self.cursor = self.db.cursor()
        except Exception as e:
            print('Wrong')
            print(e)
    def schemas_tables_count(self,sql,db):
        try:  
            self.cursor.execute(sql)
            v_result=self.cursor.fetchall()
            #print(v_result)
            count = 0
            for i in range(len(v_result)):
                #print(v_result[i][1],'--',v_result[i][0])
                count = int(v_result[i][0]) + count
            print(db,'Count Tables','--',count)
        except Exception as e:
            print('Wrong--schemas_tables_count()')
            print(e)
    def schemas_tables_list(self,sql):
        try:
            self.cursor.execute(sql)
            v_result=self.cursor.fetchall()
            #print(v_result)
            return v_result
        except Exception as e:
            print('Wrong--schemas_tables_list()')
            print(e)
    def schemas_tables_columns_list(self,sql,data):
        try:
            self.cursor.execute(sql,A=data)
            v_result=self.cursor.fetchall()
            return v_result
        except Exception as e:
            print('schemas_tables_columns_list')
            print(e)
    def schemas_tables_indexes_list(self,sql,data):
        try:
            self.cursor.execute(sql,A=data)
            v_result=self.cursor.fetchall()
            return v_result
        except Exception as e:
            print('schemas_tables_indexes_list')
            print(e)
    def close(self):
        self.db.close()
schemas_tables_count_sql = "SELECT COUNT(1),S.OWNER FROM DBA_TABLES S WHERE S.OWNER in ('PAY','BOSS','SETTLE','ISMP','TEMP_DSF','ACCOUNT') GROUP BY S.OWNER"
schemas_tables_list_sql  = "SELECT S.OWNER||'.'||S.TABLE_NAME FROM DBA_TABLES S WHERE S.OWNER in ('PAY','BOSS','SETTLE','ISMP','TEMP_DSF','ACCOUNT')"
schemas_tables_columns_sql = "select a.OWNER||'.'||a.TABLE_NAME||'.'||a.COLUMN_NAME||'.'||a.DATA_TYPE||'.'||a.DATA_LENGTH from dba_tab_columns a where a.OWNER||'.'||a.TABLE_NAME = :A"
schemas_tables_indexes_sql = "SELECT T.table_owner||'.'||T.table_name||'.'||T.index_name FROM DBA_INDEXES T WHERE T.table_owner||'.'||T.table_name = :A"
jx_db  = Oracle_Status_Output('dbadmin','QazWsx12','106.15.109.134:1522/paydb')
pro_db = Oracle_Status_Output('dbadmin','QazWsx12','localhost:1521/paydb')
jx_db.schemas_tables_count(schemas_tables_count_sql,'JX ')
pro_db.schemas_tables_count(schemas_tables_count_sql,'PRO')
jx_schemas_tables  = jx_db.schemas_tables_list(schemas_tables_list_sql)
pro_schemas_tables = pro_db.schemas_tables_list(schemas_tables_list_sql)
#print(jx_schemas_tables)
#print(pro_schemas_tables)
def diff_jx_pro(listA,listB,listClass):
    if listA !=[] and listB !=[]:
        #listD  = list(set(listA).union(set(listB)))
        listC  = sorted(list(set(listA).intersection(set(listB))))
        listAC = sorted(list(set(listA).difference(set(listC))))
        listBC = sorted(list(set(listB).difference(set(listC))))
        #if sorted(listD) == sorted(listC):
        #    print('All Tables OK')
        if listC == []:
            #print('JX ',listClass,':',listA)
            #print('PRO ',listClass,':',listB)
            print('Intersection>>','JX ',listClass,':',listAC,'--->','PRO',listClass,':',listBC)
        elif listAC != [] or listBC != []:
            print('Difference  >>','JX ',listClass,':',listAC,'--->','PRO',listClass,':',listBC)
        else:
            pass
        return listC
       
if __name__ == '__main__':
    #diff_jx_pro(jx_schemas_tables,pro_schemas_tables)
    tables_lists = diff_jx_pro(jx_schemas_tables,pro_schemas_tables,'Tables')
    for i in range(len(tables_lists)):
        table_name = "".join(tuple(tables_lists[i]))
        #print(table_name)
        jx_schemas_tables_columns = jx_db.schemas_tables_columns_list(schemas_tables_columns_sql,table_name)
        pro_schemas_tables_columns = pro_db.schemas_tables_columns_list(schemas_tables_columns_sql,table_name)
        diff_jx_pro(jx_schemas_tables_columns,pro_schemas_tables_columns,'Columns')
    for i in range(len(tables_lists)):
        table_name = "".join(tuple(tables_lists[i]))
        #print(table_name)
        jx_schemas_tables_indexes = jx_db.schemas_tables_indexes_list(schemas_tables_indexes_sql,table_name)
        pro_schemas_tables_indexes = pro_db.schemas_tables_indexes_list(schemas_tables_indexes_sql,table_name)
        diff_jx_pro(jx_schemas_tables_indexes,pro_schemas_tables_indexes,'Indexes')
    jx_db.close()
    pro_db.close()
    print('------------Table, column and index check completed--------------')

来源:https://xercis.blog.csdn.net/article/details/124410922

标签:Python,数据库,同名表,字段名
0
投稿

猜你喜欢

  • pygame多种方式实现屏保操作(自动切换、鼠标切换、键盘切换)

    2022-12-08 20:39:49
  • 有关将idea的系统配置文件移到其它盘激活失效的问题

    2022-02-16 09:33:37
  • Python Mock模块原理及使用方法详解

    2023-03-31 14:13:56
  • 页面无刷新调用数据(IFRAME+js)

    2009-06-01 11:29:00
  • python logging模块的使用

    2021-09-20 18:57:05
  • Pygame实战之实现经典外星人游戏

    2021-05-10 00:31:44
  • 详解pandas获取Dataframe元素值的几种方法

    2022-12-28 07:30:01
  • 基于Go语言实现分金币游戏

    2023-06-22 06:49:28
  • pytorch tensor int型除法出现的问题

    2021-05-18 13:18:17
  • python 实现aes256加密

    2021-01-20 22:31:38
  • Python中的异常类型及处理方式示例详解

    2022-10-27 14:55:58
  • Python pyecharts数据可视化实例详解

    2023-06-28 01:35:30
  • CodeIgniter分页类pagination使用方法示例

    2023-11-24 10:33:05
  • 深入解析MySQL索引的原理与优化策略

    2024-01-19 02:29:02
  • python第三方库visdom的使用入门教程

    2021-12-08 22:32:51
  • Python切片用法实例教程

    2023-09-28 15:26:17
  • Python3一行代码实现图片文字识别的示例

    2021-11-22 06:45:51
  • 如何实现让每句话的头一个字母都大写?

    2010-05-24 18:26:00
  • golang游戏等资源压缩包创建和操作方法

    2024-04-30 10:00:22
  • Python判断某个用户对某个文件的权限

    2023-12-15 01:25:27
  • asp之家 网络编程 m.aspxhome.com