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

目录
  • 查看两个数据库的同名表的字段名差异
    • 问题描述
    • 解决方案
    • mysql-utilities
  • 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

也可以使用专门的工具——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

优点:比较内容更详尽

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

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--------------')

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • flask/django 动态查询表结构相同表名不同数据的Model实现方法

    1.问题 为了控制数据的增长,经常需要分表,数据库中存在多张结构相同,表名相关的表,如: table_201706 table_201707 table_201708 怎么通过SQLAlchemy 或者django查询相关的数据表,而不用每次都创建Model呢 2.解决方法 分别在flask和django下实现,代码如下 2.1 flask+sqlalchemy # -*-coding:utf-8 class NewDynamicModel(object): """ 动态产生

  • python执行数据库的查询操作实例讲解

    1.fetchone该方法获取下一个查询结果集.结果集是一个对象. 2.fetchall接收全部的返回结果行. 3.rowcount这是一个只读属性,并返回执行execute方法后影响的行数. 实例 from pymysql import * def main(): # 创建Connection连接 conn = connect(host='localhost',port=3306,user='root',password='mysql',database='jing_dong',charset

  • python 两个数据库postgresql对比

    这篇文章主要介绍了python 两个数据库postgresql对比,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 比较两个postgresql数据库,原理 比较数据库中各表的大小 1. 数据库查询语句 2. python字典比较 import psycopg2 import sys class PdbModel: def __init__(self, host, dbname, username='postgres', password='po

  • python 获取sqlite3数据库的表名和表字段名的实例

    Python中对sqlite3数据库进行操作时,经常需要用到字段名,然而对于sqlite使用select语句并不能象MySql等数据库一样返回带字段名的字典数据集.特别是对于一个不熟悉的sqlite数据库,写代码时如果需要借助工具查看,那其实是有点对不起python的. 下面两段代码就可以轻易获得一个sqlite数据库中所有数据表名和字段名的列表: # python 获取sqlite3数据库mydb.db中的表名和表字段名 import sqlite3 conn=sqlite3.connect(

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

    目录 查看两个数据库的同名表的字段名差异 问题描述 解决方案 mysql-utilities Python数据库之间差异对比 查看两个数据库的同名表的字段名差异 问题描述 开发过程中有多个测试环境,测试环境 A 加了字段,测试环境 B 忘了加,字段名对不上,同一项目就报错了 CREATE DATABASE `a` CHARACTER SET 'utf8' COLLATE 'utf8_general_ci'; CREATE DATABASE `b` CHARACTER SET 'utf8' COL

  • 修改MySQL数据库中表和表中字段的编码方式的方法

    今天向MySQL数据库中的一张表添加含有中文的数据,可是老是出异常,检查程序并没有发现错误,无奈呀,后来重新检查这张表发现表的编码方式为latin1并且原想可以插入中文的字段的编码方式也是latin1,然后再次仔细观察控制台输出的异常,进一步确定是表和表中字段编码不当造成的,那就修改表和其中对应的字段呗,网上找了一会儿,你别说还真有,执行完sql脚本后果然可以存入中文了,尽管如此还是认为有必要总结一下,古人云:好记性不如烂笔头嘛,呵呵呵. 修改表的编码方式:ALTER TABLE `test`

  • access数据库的一些少用操作,ASP,创建数据库文件,创建表,创建字段,ADOX

    复制代码 代码如下: <%@LANGUAGE="VBSCRIPT" CODEPAGE="936"%> <% if Trim(Request.Form("TableName")) '----设置 打开数据库连接 dbs="Data Source="+server.mappath("database.mdb")+";Provider=Microsoft.Jet.OLEDB.4.0;&

  • sqlserver数据库中的表、字段sql语句

    1.系统表sysobjects 在数据库中创建的每个对象(例如约束.默认值.日志.规则以及存储过程)都对应一行. 列名 数据类型 说明 name sysname 对象名 id int 对象标识号 xtype char(2) 对象类型.可以是以下对象类型之一: AF = 聚合函数 (CLR) C = CHECK 约束 D = 默认值或 DEFAULT 约束 F = FOREIGN KEY 约束 L = 日志 FN = 标量函数 FS = 程序集 (CLR) 标量函数 FT = 程序集 (CLR)

  • mssql数据库中的表、字段sql语句

    mssql update from 语法 复制代码 代码如下: update a set a.columnname=b.columnname from a,b where b.id=1 1.系统表sysobjects 在数据库中创建的每个对象(例如约束.默认值.日志.规则以及存储过程)都对应一行. 列名 数据类型 说明 name sysname 对象名 id int 对象标识号 xtype char(2) 对象类型.可以是以下对象类型之一: AF = 聚合函数 (CLR) C = CHECK 约

  • 草稿整理后mysql两个数据库结构对比

    目录 1.草稿: 2.整理: 3.无注释 总结 1.草稿: -- 1.将mysql分隔符从;设置为& DELIMITER & -- 2.如果存在存储过程getdatabaseCount则删除 DROP PROCEDURE IF EXISTS `getdatabaseCount` & -- 3.定义存储过程,获取特定数据库的数量 -- (传入参数database_name字符串类型,为数据库名:传出参数count_date整数类型,为数量) CREATE DEFINER=`root`

  • MariaDB Spider 数据库分库分表实践记录

    目录 分库分表 部署 MariaDB 实例 Docker 部署 虚拟机部署 MariaDB 配置 检查每个实例 配置 Spider 远程表 基准性能测试 加入后端数据库 哈希分片 根据值范围分片 根据列表分片 分库分表 一般来说,数据库分库分表,有以下做法: 按哈希分片:根据一条数据的标识计算哈希值,将其分配到特定的数据库引擎中: 按范围分片:根据一条数据的标识(一般是值),将其分配到特定的数据库引擎中: 按列表分片:根据某些字段的标识,如果符合条件则分配到特定的数据库引擎中. 分库分表的做法有

  • MySQL之终端Terminal(dos界面)管理数据库、数据表、数据的基本操作

    MySQL有很多的可视化管理工具,比如"mysql-workbench"和"sequel-pro-". 现在我写MySQL的终端命令操作的文章,是想强化一下自己对于MySQL的理解,总会比使用图形化的理解透彻,因为我本来就比较喜欢写代码.同时写出来这些文章,是想要给大家当个参考,希望也能对大家有所帮助,有所提升,这就是我为什么要写终端操作MySQL的文章了. 注意:MySQL数据库命令不区分大小写.但在MAC的终端,如果你想使用tab自动补全命令,那么你就必须使用大

  • SQL Server创建数据库和数据表的相关约束实现方法

    本文分析了SQL Server创建数据库和数据表的相关约束实现方法.分享给大家供大家参考,具体如下: 创建约束语法如下: CREATE DATABASE [test] ON (NAME=N'test',FILENAME=N'd:\SQL2kt_Data\test.mdf',SIZE=3mb,MAXSIZE=UNLIMITED,FILEGROWTH=1MB) LOG ON (NAME=N'test_log',FILENAME=N'd:\SQL2kt_Data\test_log.ldf',SIZE=

  • SQL提取数据库表名及字段名等信息代码示例

    本文向大家介绍了使用SQL语句提取数据库所有表的表名.字段名的实例代码,在SQLserver 中进行了测试,具体内容如下: --查询所有用户表所有字段的特征 SELECT D.Name as TableName, A.colorder AS ColOrder, A.name AS Name, COLUMNPROPERTY(A.ID,A.Name, 'IsIdentity') AS IsIdentity, CASE WHEN EXISTS (SELECT 1 FROM dbo.sysobjects

随机推荐