Python怎样查看和对比数据库同名表的字段差异
Admin 2022-09-08 群英技术资讯 1065 次浏览
今天小编跟大家讲解下有关“Python怎样查看和对比数据库同名表的字段差异”的内容 ,相信小伙伴们对这个话题应该有所关注吧,小编也收集到了相关资料,希望小伙伴们看了有所帮助。开发过程中有多个测试环境,测试环境 A 加了字段,测试环境 B 忘了加,字段名对不上,同一项目就报错了

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 中的 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
效果

--- 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
优点:比较内容更详尽
缺点:无法批量,要自己指定比较对象(稍微改写即可克服)
此脚本用于两个数据库之间的表、列、栏位、索引的差异对比。
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--------------')
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
数据可视化是数据科学中关键的一步,下面这篇文章主要给大家介绍了关于如何利用Python绘制动态可视化图表的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
这篇文章主要给大家分享Python条件语句的用法,对新手学习条件语句具有一定的借鉴和学习价值,感兴趣的朋友可以参考一下,希望大家阅读完这篇文章能有所收获,下面我们一起来学习一下吧。
这篇文章主要介绍了python数据结构算法分析,在python的数据结构的章节中,我们上次学习到了python面向对象的思想,即我们想用程序来实现一个东西,我们需是用对象的特征来描述我们想构建的对象。感兴趣的小伙伴可以查看下面内容</P><P>
这篇文章我们来了解怎样用python怎样实现扑克游戏中判断牌型的功能,在扑克游戏,判断牌型是很基础的操作,这才能进行游戏的下一步。下面我们就来看看具体要怎样去实现。
这篇文章主要介绍了Python中的内置函数isdigit(),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
成为群英会员,开启智能安全云计算之旅
立即注册关注或联系群英网络
7x24小时售前:400-678-4567
7x24小时售后:0668-2555666
24小时QQ客服
群英微信公众号
CNNIC域名投诉举报处理平台
服务电话:010-58813000
服务邮箱:service@cnnic.cn
投诉与建议:0668-2555555
Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 ICP核准(ICP备案)粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008