0 先介绍一下我们的场景和数据
我们从etl工具查到了一批源表对应目标表的结果,每张表相关的字段有db(类型,ip,port,db_name),schema,table_name,另外还记录了etl接口的信息(tran_id,trans_name)
id trans_id trans_name source_db_name source_db_type source_db_host source_db_port source_schema source_table target_db_name target_db_type target_db_host target_db_port target_schema target_table remark data_status create_by create_time update_by update_time
1 445 ODS_UDW_T_GXYX_XXSMD dcenter 1 10.8.6.131 1521 HUNAU_ODS DM_GB_MZDMB dcenter 1 10.8.6.131 1521 HUNAU_UDW T_GXYX_XSMD 0 2019-11-21 02:00:01 2019-11-21 02:00:01
2 336 SOURCE_ODS_ZC_GXZC_ZZZC_DZP_JAVA_EN zcdata 10.8.6.33 1433 GXZC_ZZZC_DZP_JAVA_EN dcenter 1 10.8.6.131 1521 HUNAU_ODS ZC_GXZC_ZZZC_DZP_JAVA_EN 0 2019-11-21 02:00:01 2019-11-21 02:00:01
1 按照单个字段去重
由于一个接口可能来自多个不同的源表,去向同一个目标表,
按照接口去重展示,如下所示
注:这个方法需要log表有一个唯一主键id
ids = DataFlowTableTransLog.objects.values('trans_id').annotate(min_id=Min('id')).values_list('min_id')
qs = DataFlowTableTransLog.objects.filter(id__in=ids, trans_id__isnull=False)
2 按照多个字段去重
理论上我们的etl接口可能是多个源schema,但不可能是多个源库,所示可以做一个验证,标示库的字段有四个,如下所示
from collections import Counter
def __check_all_db_count(_record, logs):
# 理论上同一个接口应该不存在跨库的情况,最多只有跨schema,这里做唯一验证
trans_ids = DataFlowTableTransLog.objects.values(
'trans_id', 'source_db_name', 'source_db_type', 'source_db_host', 'source_db_port').annotate(
min_id=Min('id')).values_list('trans_id', flat=True)
result = Counter(trans_ids)
err_trans_ids = [k for k, v in result.items() if v > 1]
return err_trans_ids