背景
大数据以及报表测试中,我们都需要自己写sql(查询源表),跟开发写好的sql生成数据(查询结果表)做对比。大数据数据基本都是使用impala或者hive查询。使用的ui工具就是dbvisualizer。数据过多的时候需要抽样检查,但有时候也会漏掉。使用脚本是最好的方式。
脚本逻辑
- 先获取两个返回数据,sql查询返回的是元组组合。
- 再定义要对比字段所在的元组位置。因为有些字段不需要对比。
- 通过获取key value比较两个数据库的内容,输出两者都不存在的数据。
- 关键字获取,关键字就是你比较两个数据相同的唯一标识,比如购物的时候,你的订单就是关键字。如果没有你的数据没有唯一值,那就要自己造,可以使用sql字段拼接的方式,contct起来当作唯一字段。有了关键字,就能获取到两个数据,然后根据第二步的元组位置,一一对比就可以。并根据第二步元组位置输出数据不对的字段数据
安装impala
window10下安装impala比较麻烦,需要使用到很多模块,主要的模块如下:
需要按照顺序pip安装
pure_sasl thrift_sasl thrift bitarray thriftpy impyla
其中安装bitarray impyla会提示安装可能会出现“error: Microsoft Visual C++ 14.0 is required. Get it with “Microsoft Visual C++ Build Tools”**这样的错误。对于此类问题,提供以下两种解决方案:
1 下载所需模块的.whl文件,然后再以pip的形式安装:
1)常用模块的.whl文件的下载地址:需要先确定自己的python版本。一般为32位。cp36代表你的python版本,一定要下载对,要不然会报平台错误。
2)以模块bitarray 为例,通过上面连接后下载。
pip install bitarray-1.0.1-cp36-cp36m-win32
2 最根本的解决办法:安装Microsoft Visual C++ 14.0,但这个工具很大, 需要4g左右。
安装pgsql
pip 安装 psycopg2即可
代码
#! -*- coding:utf-8 -*-
"""
# @Time : 2019/10/18
# @File : sqldata_diff.py
# @Software : PyCharm
# @Description :
"""
from impala.dbapi import connect
import psycopg2
def impala_data():
sql=''
with open(r'D:\xxx.sql', 'r+', encoding='utf-8') as f:
sql=sql+f.read()
conn = connect(host='xxxx', port=21050, user='test', password='')
cursor = conn.cursor()
# cursor.execute("SELECT * from xxx'")
cursor.execute(sql)
cdh_tabs = cursor.fetchall()
return cdh_tabs
def psql_Data():
conn = psycopg2.connect(database='xx', user='xxx', password='xxx', host='192.168.xxx', port='5432')
curs = conn.cursor()
sql='SELECT xxx'##
curs.execute(sql)
data = curs.fetchall()
curs.close()
conn.close()
return data
def pysqldatabase_keyvalue(psqldata): ###返回列表psql的关键字以及所在的元组位置。关键字必须是表里唯一的
b_dic={}
for code in range (len(psqldata)):
n=psqldata[code][6] ####关键字的位置
# n=psqldata[code][5] ####关键字的位置,此处关键字为weiyi
b_dic.setdefault(n,code)
# print (b_dic)
return b_dic
def impala_keyvalue(impaladata): ###返回列表impala的关键字以及所在的元组位置。关键字必须是表里唯一的
c_dic={}
for code in range (len(impaladata)):
n=impaladata[code][6] ####关键字的位置
# n=psqldata[code][5] ####关键字的位置,团购此处关键字为weiyi
c_dic.setdefault(n,code)
# print (b_dic)
return c_dic
if __name__=='__main__':
psqldata=psql_Data()
impaladata=impala_data()
##指标位置
impala_order={"prd_qty":4} ###需要编注指标以及对应的位置
psql_order={"prd_qty":4}
###以下是impala数据库对比pgsqk的数据库。有则对比,没有则输出不存在的。
pgkeyvalue = pysqldatabase_keyvalue(psqldata)
impalanoinsidepg = []
for i in range(len(impaladata)):
impala_key=impaladata[i][6]
if (impala_key) in pgkeyvalue.keys(): # 取出a列表的关键字去比较b表的关键字。
b3 = pgkeyvalue[impala_key] # 根据a表关键字去匹配出b表该字段所在元组的数据。
# print(b3)
print("以下是该数据%s输出" % impala_key)
for key, value in impala_order.items(): ##根据制定的取数规则,判断是否
if key in psql_order.keys():
if str(impaladata[i][value]) == str(psqldata[b3][psql_order[key]]):
# print("%s数据是对的" % key)
pass
else:
print("\033[1;34;0m\t%s数据不对\033[0m-----" % key)
print("impaladata 的数据%s,psqldata 的数据%s" % (impaladata[i][value], psqldata[b3][psql_order[key]]))
else:
print("-----\033[1;31;0m\t%s值不存在\033[0m-----" % (key))
else:
impalanoinsidepg.append(impala_key)
print("以下%d条impala数据是不存在pg数据库表里%s" % (len(impalanoinsidepg),impalanoinsidepg))
###以下是pgsqk的数据库对比impala数据库。有则对比,没有则输出不存在的。
impalakeyvalue = impala_keyvalue(impaladata)
pgnoinsideimpala = []
for i in range(len(psqldata)):
pg_key=psqldata[i][6]
if (pg_key) in impalakeyvalue.keys():
pass
else:
pgnoinsideimpala.append(pg_key)
print("以下%d条pg数据是不存在impala数据库表里%s" % (len(pgnoinsideimpala),pgnoinsideimpala))