python比对Excel表和json数据

注:由于我不是做专业数据处理的,懂得也不多,所以编写的python代码都是简单易懂的,如果存在bug或者有更好的实现方法,欢迎各位大佬指出!!!

前段时间,测试小白我接到了老大的新活,比对mysql数据库和Excel源表。虽然数据测试这块我确实没接触过,但是本着咱就是块砖的原则,哪里需要往哪搬,那就火速开干呗。

一开始打算用Python连接读取数据库,再读取Excel表来比对数据的方案,奈何数据库我又没有权限,只有一个可视化数据库Metabase的导出权限。我捣鼓了一下,Metabase导出json格式数据是没问题的,于是就变成了Excel表和json数据比对。

那么方向定好了,接下来该怎么比对呢?(陷入沉思...)

既然用python比对,那么首先得转换成相同数据类型,才好比对,那么初步方案就是将Excel和json读取后,都转成列表中嵌套多个字典类型数据,也就是[{},{},{}...]这样的格式数据。

首先是读取Excel数据,将其转成[{},{},{}...]格式,下图是实现后输出。

以下是代码实现思路:

"""
    @功能:用于读取Excel中数据,并将其转换为[{},{},{}...]
"""

# 根据excel路径及 sheet页名称将对应的sheet页内容读入到字典中
def read_excel_into_list(excel_file_path, sheet_name):
    # 1、根据excel路径将数据读入到工作薄中(读入内存)
    work_book = file_read_write_utils.read_from_excel(excel_file_path)
    # 2、将对应的sheet页内容读入到字典中
    sheet = work_book.sheet_by_name(sheet_name)
    return convert_sheet_context_into_list(sheet, sheet_name)


# 将对应的sheet页内容读入到字典中
def convert_sheet_context_into_list(sheet, sheet_name):
    fld_key_list = []
    fld_val_list = []
    new_val_list = []
    new_val_list2 = []
    for col_index in range(sheet.nrows):
        for row_index in range(sheet.ncols):
            # 将栏位名称存入fld_key_list
            fld_key_list.append(sheet.cell_value(0, row_index))
            # 将第二行及之后栏位值存入fld_value_list
            if col_index >= 1:
                fld_val_list.append(sheet.cell_value(col_index, row_index))
        if col_index >= 1:
            dict1 = dict(zip(fld_key_list, fld_val_list))
            new_val_list.append(dict1)

    if sheet_name == 'XXXX':
        for table in new_val_list:
            new_val_list2.append(table)
            i = table_none_format(new_val_list2)
        print(f'共{i}行')
    # print("根据Excel表格读取到的列表为: \n" + str(new_val_list2))
    return new_val_list2

接下来是读取json数据,将其转成[{},{},{}...]格式,下图是实现后输出。

以下是代码实现思路:


import json
import os

import xlrd2
import xlwt
from xlutils.copy import copy


# 将json文件对象中的数据直接转换成 Python 列表
def read_from_json(json_file_path, model, char_set):
    i = 0
    if '' == json_file_path.strip():
        json_file_path = json_file_path
    if '' == char_set.strip():
        char_set = "UTF-8"
    if '' == model.strip():
        model = "r"

    with open(json_file_path, model, encoding=char_set) as f:
        json_data = json.load(f)
        for table in json_data['data']:
            i += 1
        # print("根据json报文读取到的列表为:\n" + str(json_data['data']))
        print(f"共{i}行")   
        return json_data['data']

那么读取完数据后,接下来就是对同一数据类型的数据进行比对。由于我的两组数据没有唯一主键,所以在比对过程中,我通过数据中每个字典的两个或多个关键字段来标识唯一性(由于数据建模时,两个或多个关键字段可标识该条数据的唯一性,具体需要看实际项目数据情况~~),下图是实现后输出。

以下是代码实现思路:

"""
    @功能:比较两个列表中的字典是否相同
    注意:1、由于比对的mysql表精度和Excel精度可能存在差异,需要在之前进行数据处理
"""


def compare_all_different(list1, list2):
    diff = []
    i = 0
    a = 0
    print("开始比较list1(表格读取) 和 list2(json读取) 的所有差异:")
    # 首先判断Excel 和 json 数据总数是否一致
    if len(list1) != len(list2):
        print("表格数据总数和json数据总数对应不上!")
    else:
        # 其次获取list1中的一条字典数据,再获取list2中对应的一条字典数据,进行两条字典数据的比对
        for dict1 in list1:
            year = dict1['年份']  # 年份
            province_name = dict1['地区']  # 地区
            gdp = dict1['gdp']  # gdp
            gdp_person = dict1['gdp_person'] # gdp_person
            # 通过一个字段标志另一个列表中的唯一字典
            dict2 = get_dict_wih_same_key(new_list1=[year, province_name, gdp, gdp_person], list2=list2)
            # 接下来就是两条字典数据比对
            try:
                differ = set(dict1.items()) ^ set(dict2.items())
                a += 1
                if len(differ) != 0:
                    i += 1
                    print(f"【{i}】--\ndict1(表格读取):\n{dict1}\ndict2(json读取):\n{dict2}\n相同关键字的栏位取值有差异,差异是:{differ}")
                    for item in list(differ):
                        diff.append(item)
                else:
                    # i += 1
                    # print(f"第{i}行数据比对一致")
                    pass
            except AttributeError:
                pass
        print(a)
        return diff


def get_dict_wih_same_key(new_list1, list2):
    i = 0
    for dict2 in list2:
        if dict2['年份'] == new_list1[0] and dict2['地区'] == new_list1[1]:
                return dict2

以上就是测试小白我的小小拙见啦,新的一年,希望各位事事顺心哦~~

猜你喜欢

转载自blog.csdn.net/xiaolu_z/article/details/128533231