数据支撑【对数据】

前言

最近项目架构做了大的调整,很多数据表都要重新生产,新数据上线需要与旧数据做下校验,领导让我做个简单的工具来对比数据。

校验逻辑

首先定义表的对比指标,然后计算出两表的指标值,然后进行对比。指标如下:

  • 总数:count
  • 均值:mean
  • 标准差:stddev
  • 最大值:max
  • 最小值:min
  • 上四分位数:25%
  • 中位数:50%
  • 下四分位数:75%

处理代码

# coding=utf-8
import sys
import pandas as pd
from pyspark.sql import SparkSession

pd.options.display.max_columns = None
pd.options.display.max_rows = None

from texttable import Texttable


# from pyspark import SparkConf, SparkContext, HiveContext


def run_task(source_table, target_table):
    """
    对比指标:
        1、总条数 count
        2、去重后的条数 distinct_count
        3、最大值 max
        4、最小值 min
        5、总数 sum

    :param source_table:
    :param target_table:
    :return:
    """
    task_name = "data-verification-%s-%s" % (source_table, target_table)
    spark = SparkSession.builder.appName(task_name).enableHiveSupport().getOrCreate()

    # conf = SparkConf().set('spark.storage.blockManagerHeartBeatMs', 300000) \
    #     .set('spark.shuffle.io.serverThreads', 8) \
    #     .set('spark.shuffle.io.clientThreads', 8) \
    #     .set('spark.storage.blockManagerSlaveTimeoutMs', 300000).setAppName(task_name)
    # sc = SparkContext(conf=conf)
    # hiveContext = HiveContext(sc)

    # hiveContext.sql("use %s" % database)
    s_df = spark.sql("select * from %s" % source_table)
    t_df = spark.sql("select * from %s" % target_table)

    ss_df = s_df.summary()
    st_df = t_df.summary()

    ss_pdf = ss_df.toPandas().set_index("summary").T

    print("原始表统计结果:")
    ss_pdf.index.name = 'summary'
    ss_pdf['summary'] = ss_pdf.index
    ss_pdf = ss_pdf[['summary', 'count', 'mean', 'stddev', 'min', 'max', '25%', '50%', '75%']]
    ss_tb = Texttable()
    ss_tb.set_cols_align(['l', 'r', 'r', 'r', 'r', 'r', 'r', 'r', 'r'])
    ss_tb.set_cols_dtype(['t', 't', 't', 't', 't', 't', 't', 't', 't'])
    ss_tb.set_cols_width([15, 10, 15, 15, 15, 15, 15, 15, 15])
    ss_tb.header(ss_pdf.columns.values)
    ss_tb.add_rows(ss_pdf.values, header=False)
    print(ss_tb.draw())
    print("\n")

    st_pdf = st_df.toPandas().set_index("summary").T
    print("新表统计结果:")
    st_pdf.index.name = 'summary'
    st_pdf['summary'] = ss_pdf.index
    st_pdf = ss_pdf[['summary', 'count', 'mean', 'stddev', 'min', 'max', '25%', '50%', '75%']]
    st_tb = Texttable()
    st_tb.set_cols_align(['l', 'r', 'r', 'r', 'r', 'r', 'r', 'r', 'r'])
    st_tb.set_cols_dtype(['t', 't', 't', 't', 't', 't', 't', 't', 't'])
    st_tb.set_cols_width([15, 10, 15, 15, 15, 15, 15, 15, 15])
    st_tb.header(st_pdf.columns.values)
    st_tb.add_rows(st_pdf.values, header=False)
    print(st_tb.draw())
    print("\n")

    spark.stop()


if __name__ == "__main__":
    source_table = sys.argv[1]
    target_table = sys.argv[2]

    run_task(source_table, target_table)

启动脚本

#!/bin/bash

export LANG="en_US.UTF-8"
export PYTHONIOENCODING=utf8

source=$1
target=$2

if [ ! -n "$source" ]; then
  echo pls input source_table
  exit 1
else
  echo source : $source
fi

if [ ! -n "$target" ]; then
  echo pls input target_table
  exit 1
else
  echo target : $target
fi

spark-submit \
    --master yarn \
    --queue mid \
    --num-executors 10 \
    --driver-memory 5g \
    --executor-memory 15g \
    --executor-cores 2 \
    --py-files ./data-verification.zip \
    scripts/data_diff.py $source $target

输出结果

原始表统计结果:
+-----------------+------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+
|     summary     |   count    |      mean       |     stddev      |       min       |       max       |       25%       |       50%       |       75%       |
+=================+============+=================+=================+=================+=================+=================+=================+=================+
| id              |          2 |             1.5 | 0.7071067811865 |               1 |               2 |               1 |               1 |               2 |
|                 |            |                 |             476 |                 |                 |                 |                 |                 |
+-----------------+------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+
| name            |          2 |            None |            None |           david |           david |            None |            None |            None |
+-----------------+------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+
| salary          |          2 |         15000.0 | 7071.0678118654 |           10000 |           20000 |           10000 |           10000 |           20000 |
|                 |            |                 |              75 |                 |                 |                 |                 |                 |
+-----------------+------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+
| desc            |          2 |            None |            None |      一月份工资  |      二月份工资  |            None |            None |            None |
+-----------------+------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+


新表统计结果:
+-----------------+------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+
|     summary     |   count    |      mean       |     stddev      |       min       |       max       |       25%       |       50%       |       75%       |
+=================+============+=================+=================+=================+=================+=================+=================+=================+
| id              |          2 |             1.5 | 0.7071067811865 |               1 |               2 |               1 |               1 |               2 |
|                 |            |                 |             476 |                 |                 |                 |                 |                 |
+-----------------+------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+
| name            |          2 |            None |            None |           david |           david |            None |            None |            None |
+-----------------+------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+
| salary          |          2 |         15000.0 | 7071.0678118654 |           10000 |           20000 |           10000 |           10000 |           20000 |
|                 |            |                 |              75 |                 |                 |                 |                 |                 |
+-----------------+------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+
| desc            |          2 |            None |            None |      一月份工资  |      二月份工资  |            None |            None |            None |
+-----------------+------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+

本次案例采用pyspark开发,需要注意python的运行环境,笔者采用的是anaconda3,需要安装的依赖有pandas、texttable,直接在yarn client机器上安装。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,287评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,346评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,277评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,132评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,147评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,106评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,019评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,862评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,301评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,521评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,682评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,405评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,996评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,651评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,803评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,674评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,563评论 2 352

推荐阅读更多精彩内容