注:由于我不是做专业数据处理的,懂得也不多,所以编写的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
以上就是测试小白我的小小拙见啦,新的一年,希望各位事事顺心哦~~